]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGCF/Correlations/Base/AliAnalyseLeadingTrackUE.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWGCF / Correlations / Base / AliAnalyseLeadingTrackUE.cxx
index a8851ceac793cacefc0b4697a69730283d33e794..c51542e8db428ed341bf84ab9da2891e369776de 100644 (file)
  * about the suitability of this software for any purpose. It is          *
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
-//#include <TBranch.h>
-//#include <TCanvas.h>
-//#include <TChain.h>
-//#include <TFile.h>
-//#include <TH1F.h>
-//#include <TH1I.h>
-//#include <TH2F.h>
+
 #include <TList.h>
-//#include <TLorentzVector.h>
 #include <TMath.h>
 #include <TObjArray.h>
 #include <TObject.h>
-//#include <TProfile.h>
-//#include <TRandom.h>
-//#include <TSystem.h>
-//#include <TTree.h>
 #include <TVector3.h>
 
 #include "AliAnalyseLeadingTrackUE.h"
-//#include "AliAnalysisTask.h"
 
-//#include "AliAnalysisHelperJetTasks.h"
-//#include "AliAnalysisManager.h"
 #include "AliAODEvent.h"
-//#include "AliAODHandler.h"
-//#include "AliAODJet.h"
 #include "AliAODMCParticle.h"
 #include "AliAODTrack.h"
 #include "AliESDEvent.h"
 #include "AliESDtrack.h"
 #include "AliESDtrackCuts.h"
-//#include "AliGenPythiaEventHeader.h"
 #include "AliInputEventHandler.h"
-//#include "AliKFVertex.h"
-//#include "AliLog.h"
 #include "AliMCEvent.h"
 #include "AliVParticle.h"
 #include "AliAODMCHeader.h"
+#include "TFormula.h"
 
 #include "AliAnalysisManager.h"
 #include "AliMCEventHandler.h"
 #include "AliStack.h"
+#include "AliPIDResponse.h"
+#include "AliHelperPID.h"
 
 
 ////////////////////////////////////////////////
@@ -72,13 +56,22 @@ AliAnalyseLeadingTrackUE::AliAnalyseLeadingTrackUE() :
   TObject(),
   fDebug(0),
   fFilterBit(16),
+  fTrackStatus(0),
   fOnlyHadrons(kFALSE),
+  fCheckMotherPDG(kTRUE),
   fTrackEtaCut(0.8),
+  fTrackEtaCutMin(-1.),
   fTrackPtMin(0),
   fEventSelection(AliVEvent::kMB|AliVEvent::kUserDefined),
+  fDCAXYCut(0),
+  fSharedClusterCut(-1),
+  fCrossedRowsCut(-1),
+  fFoundFractionCut(-1),
   fEsdTrackCuts(0x0), 
-  fEsdTrackCutsSPD(0x0), 
-  fEsdTrackCutsSDD(0x0) 
+  fEsdTrackCutsExtra1(0x0), 
+  fEsdTrackCutsExtra2(0x0), 
+  fHelperPID(0x0),
+  fEventCounter(0)
 {
   // constructor
 }
@@ -107,7 +100,7 @@ Bool_t AliAnalyseLeadingTrackUE::ApplyCuts(TObject* track)
   
   // select track according to set of cuts
   if (!fEsdTrackCuts->IsSelected(track) )return kFALSE;
-  if (fEsdTrackCutsSPD && fEsdTrackCutsSDD && !fEsdTrackCutsSPD->IsSelected(track) && fEsdTrackCutsSDD->IsSelected(track)) return kFALSE;
+  if (fEsdTrackCutsExtra1 && fEsdTrackCutsExtra2 && !fEsdTrackCutsExtra1->IsSelected(track) && !fEsdTrackCutsExtra2->IsSelected(track)) return kFALSE;
 
   return kTRUE;
 }
@@ -152,18 +145,44 @@ void AliAnalyseLeadingTrackUE::DefineESDCuts(Int_t filterbit) {
     fEsdTrackCuts->SetMinNCrossedRowsTPC(70);
     fEsdTrackCuts->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
   }
+  else if (filterbit == 2048) // mimic hybrid tracks
+  {
+    // correspond to esdTrackCutsHTG, but WITHOUT spd constraint. this is checked with the next object
+    fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kFALSE);
+    fEsdTrackCuts->SetName("Global Hybrid tracks, loose DCA");
+    fEsdTrackCuts->SetMaxDCAToVertexXY(2.4);
+    fEsdTrackCuts->SetMaxDCAToVertexZ(3.2);
+    fEsdTrackCuts->SetDCAToVertex2D(kTRUE);
+    fEsdTrackCuts->SetMaxChi2TPCConstrainedGlobal(36);
+    fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
+    fEsdTrackCuts->SetMaxFractionSharedTPCClusters(0.4);
+
+    // Add SPD requirement 
+    fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
+    fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    // A track passing fEsdTrackCuts and fEsdTrackCutsExtra1 corresponds to esdTrackCutsHTG
+
+    fEsdTrackCutsExtra2 = new AliESDtrackCuts("No_SPD", "Reject tracks with cluster in SPD");
+    fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kNone);
+    // A track passing fEsdTrackCuts and fEsdTrackCutsExtra2 corresponds to esdTrackCutsHTGC and needs to be constrained
+  }
+  else if (filterbit == 4096) // require TOF matching
+  {
+    fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kTRUE);
+    // FIXME: TOF REQUIREMENTS ARE IN GetParticleSpecies FOR THE MOMENT
+  }
   else
   {
-    fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010();
-    fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kNone);
+    fEsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011();
+    fEsdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kOff);
 
     // Add SPD requirement 
-    fEsdTrackCutsSPD = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
-    fEsdTrackCutsSPD->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    fEsdTrackCutsExtra1 = new AliESDtrackCuts("SPD", "Require 1 cluster in SPD");
+    fEsdTrackCutsExtra1->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
 
     // Add SDD requirement 
-    fEsdTrackCutsSDD = new AliESDtrackCuts("SDD", "Require 1 cluster in first layer SDD");
-    fEsdTrackCutsSDD->SetClusterRequirementITS(AliESDtrackCuts::kSDD,AliESDtrackCuts::kFirst);
+    fEsdTrackCutsExtra2 = new AliESDtrackCuts("SDD", "Require 1 cluster in first layer SDD");
+    fEsdTrackCutsExtra2->SetClusterRequirementITS(AliESDtrackCuts::kSDD,AliESDtrackCuts::kFirst);
   }
 }
 
@@ -186,7 +205,7 @@ TObjArray*  AliAnalyseLeadingTrackUE::FindLeadingObjects(TObject *obj)
        AliVParticle* part = ParticleWithCuts( obj, ipart );
         if (!part) continue;
        // Accept leading-tracks in a limited pseudo-rapidity range     
-       if( TMath::Abs(part->Eta()) > fTrackEtaCut ) continue;
+       if( TMath::Abs(part->Eta()) > fTrackEtaCut || TMath::Abs(part->Eta()) < fTrackEtaCutMin ) continue;
        tracks->AddLast( part );
        }
   // Order tracks by pT        
@@ -215,7 +234,7 @@ void AliAnalyseLeadingTrackUE::RemoveInjectedSignals(TObjArray* tracks, TObject*
     arrayMC = static_cast<TClonesArray*>(mcObj);
   else
   {
-    arrayMC->Dump();
+    mcObj->Dump();
     AliFatal("Invalid object passed");
   }
   
@@ -266,10 +285,11 @@ void AliAnalyseLeadingTrackUE::RemoveInjectedSignals(TObjArray* tracks, TObject*
       Printf("WARNING: No mother found for particle %d:", part->GetLabel());
       continue;
     }
-   
-    if (mother->GetLabel() > maxLabel)
+
+//     Printf("%d %d %d", i, part->GetLabel(), mother->GetLabel());
+    if (mother->GetLabel() >= maxLabel)
     {
-//       Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
+//       Printf("Removing %d with label %d", i, part->GetLabel()); ((AliMCParticle*)part)->Particle()->Print(); ((AliMCParticle*)mother)->Particle()->Print();
       TObject* object = tracks->RemoveAt(i);
       if (tracks->IsOwner())
        delete object;
@@ -282,18 +302,77 @@ void AliAnalyseLeadingTrackUE::RemoveInjectedSignals(TObjArray* tracks, TObject*
 }
 
 //-------------------------------------------------------------------
-TObjArray* AliAnalyseLeadingTrackUE::GetAcceptedParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts)
+void AliAnalyseLeadingTrackUE::RemoveWeakDecays(TObjArray* tracks, TObject* mcObj)
+{
+  // remove particles from weak decays
+  // <tracks> can be the following cases:
+  // a. tracks: in this case the label is taken and then case b.
+  // b. particles: it is checked if IsSecondaryFromWeakDecay is true
+  // <mcObj> can be AOD (TClonesArray) or ESD (AliMCEvent)
+  
+  TClonesArray* arrayMC = 0;
+  AliMCEvent* mcEvent = 0;
+  if (mcObj->InheritsFrom("AliMCEvent"))
+    mcEvent = static_cast<AliMCEvent*>(mcObj);
+  else if (mcObj->InheritsFrom("TClonesArray"))
+    arrayMC = static_cast<TClonesArray*>(mcObj);
+  else
+  {
+    mcObj->Dump();
+    AliFatal("Invalid object passed");
+  }
+  
+  Int_t before = tracks->GetEntriesFast();
+
+  for (Int_t i=0; i<before; ++i) 
+  {
+    AliVParticle* part = (AliVParticle*) tracks->At(i);
+    
+    if (part->InheritsFrom("AliESDtrack") || part->InheritsFrom("AliAODTrack"))
+      part = ((mcEvent) ? mcEvent->GetTrack(TMath::Abs(part->GetLabel())) : (AliVParticle*)arrayMC->At(TMath::Abs(part->GetLabel())));
+    
+    if (part->InheritsFrom("AliAODMCParticle"))
+    {
+      if (!((AliAODMCParticle*) part)->IsSecondaryFromWeakDecay())
+       continue;
+    }
+    else if (part->InheritsFrom("AliMCParticle") && mcEvent)
+    {
+      if (!(mcEvent->Stack()->IsSecondaryFromWeakDecay(part->GetLabel())))
+       continue;
+    }
+    else
+    {
+      part->Dump();
+      AliFatal("Unknown particle");
+    }
+    
+//     Printf("Removing %d with label %d", i, part->GetLabel()); part->Dump();
+    TObject* object = tracks->RemoveAt(i);
+    if (tracks->IsOwner())
+      delete object;
+  }
+  tracks->Compress();
+  
+  if (before > tracks->GetEntriesFast())
+    AliInfo(Form("Reduced from %d to %d", before, tracks->GetEntriesFast())); 
+}
+
+//-------------------------------------------------------------------
+TObjArray* AliAnalyseLeadingTrackUE::GetAcceptedParticles(TObject* obj, TObject* arrayMC, Bool_t onlyprimaries, Int_t particleSpecies, Bool_t useEtaPtCuts, Bool_t speciesOnTracks)
 {
   // Returns an array of particles that pass the cuts, if arrayMC is given each reconstructed particle is replaced by its corresponding MC particles, depending on the parameter onlyprimaries only for primaries 
   // particleSpecies: -1 all particles are returned
   //                  0 (pions) 1 (kaons) 2 (protons) 3 (others) particles
-
+  // speciesOnTracks if kFALSE, particleSpecies is only applied on the matched MC particle (not on the track itself)
+  
   Int_t nTracks = NParticles(obj);
   TObjArray* tracks = new TObjArray;
   
   // for TPC only tracks
   Bool_t hasOwnership = kFALSE;
-  if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024) && obj->InheritsFrom("AliESDEvent"))
+  if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024 || fFilterBit == 2048) && obj->InheritsFrom("AliESDEvent"))
     hasOwnership = kTRUE;
   
   if (!arrayMC)
@@ -301,16 +380,18 @@ TObjArray* AliAnalyseLeadingTrackUE::GetAcceptedParticles(TObject* obj, TObject*
  
   // Loop over tracks or jets
   for (Int_t ipart=0; ipart<nTracks; ++ipart) {
-    AliVParticle* part = ParticleWithCuts( obj, ipart, onlyprimaries, particleSpecies );
+    AliVParticle* part = ParticleWithCuts( obj, ipart, onlyprimaries, (speciesOnTracks) ? particleSpecies : -1);
     if (!part) continue;
     
     if (useEtaPtCuts)
-      if (TMath::Abs(part->Eta()) > fTrackEtaCut || part->Pt() < fTrackPtMin)
+      if (TMath::Abs(part->Eta()) > fTrackEtaCut || TMath::Abs(part->Eta()) < fTrackEtaCutMin || part->Pt() < fTrackPtMin)
       {
        if (hasOwnership)
          delete part;
         continue;
       }
+      
+//     Printf("%p %p %d Accepted %d %f %f %f", obj, arrayMC, particleSpecies, ipart, part->Eta(), part->Phi(), part->Pt());
     
     if (arrayMC) {
       Int_t label = part->GetLabel();
@@ -340,7 +421,7 @@ TObjArray* AliAnalyseLeadingTrackUE::GetFakeParticles(TObject* obj, TObject* arr
 
   // for TPC only tracks
   Bool_t hasOwnership = kFALSE;
-  if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024) && obj->InheritsFrom("AliESDEvent"))
+  if ((fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024 || fFilterBit == 2048) && obj->InheritsFrom("AliESDEvent"))
     hasOwnership = kTRUE;
 
   tracksReconstructed->SetOwner(hasOwnership);
@@ -352,7 +433,7 @@ TObjArray* AliAnalyseLeadingTrackUE::GetFakeParticles(TObject* obj, TObject* arr
     if (!partReconstructed) continue;
 
     if (useEtaPtCuts)
-      if (TMath::Abs(partReconstructed->Eta()) > fTrackEtaCut || partReconstructed->Pt() < fTrackPtMin)
+      if (TMath::Abs(partReconstructed->Eta()) > fTrackEtaCut || TMath::Abs(partReconstructed->Eta()) < fTrackEtaCutMin || partReconstructed->Pt() < fTrackPtMin)
       {
         if (hasOwnership)
           delete partReconstructed;
@@ -362,13 +443,26 @@ TObjArray* AliAnalyseLeadingTrackUE::GetFakeParticles(TObject* obj, TObject* arr
     Int_t label = partReconstructed->GetLabel();
     if (label == 0)
     {
+      /*
+      Printf(">>> TPC only track:");
+      partReconstructed->Print();
+      partReconstructed->Dump();
+      Printf(">>> Global track:");
+      ((AliESDEvent*) obj)->GetTrack(ipart)->Dump();
+      Printf("Fake (TPC only): eta = %f, phi = %f, pT = %f, ncl = %d, dedx = %f", partReconstructed->Eta(), partReconstructed->Phi(), partReconstructed->Pt(), ((AliESDtrack*) partReconstructed)->GetTPCclusters(0), ((AliESDtrack*) partReconstructed)->GetTPCsignal());
+      Printf("Fake (global  ): eta = %f, phi = %f, pT = %f, ncl = %d, dedx = %f", ((AliESDEvent*) obj)->GetTrack(ipart)->Eta(), ((AliESDEvent*) obj)->GetTrack(ipart)->Phi(), ((AliESDEvent*) obj)->GetTrack(ipart)->Pt(), ((AliESDEvent*) obj)->GetTrack(ipart)->GetTPCclusters(0), ((AliESDEvent*) obj)->GetTrack(ipart)->GetTPCsignal());
+      */
       tracksFake->AddLast(partReconstructed);
       continue;
     }
-    if (hasOwnership)
-      delete partReconstructed;
+
     AliVParticle* partOriginal = ParticleWithCuts(arrayMC, TMath::Abs(label),onlyprimaries, particleSpecies);
-    if (!partOriginal)continue;
+    if (!partOriginal)
+    {
+      if (hasOwnership)
+       delete partReconstructed;
+      continue;
+    }
 
     tracksReconstructed->AddLast(partReconstructed);
     tracksOriginal->AddLast(partOriginal);
@@ -447,7 +541,6 @@ Int_t  AliAnalyseLeadingTrackUE::NParticles(TObject* obj)
   return nTracks;
 }
 
-
 //-------------------------------------------------------------------
 AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ipart, Bool_t onlyprimaries, Int_t particleSpecies)
 {
@@ -473,8 +566,9 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
         if (particleSpecies != -1) {
                 // find the primary mother
                 AliVParticle* mother = part;
-                while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
-                {
+                if(fCheckMotherPDG) {
+                 while (!((AliAODMCParticle*)mother)->IsPhysicalPrimary())
+                 {
                   if (((AliAODMCParticle*)mother)->GetMother() < 0)
                   {
                     mother = 0;
@@ -484,8 +578,8 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
                   mother = (AliVParticle*) arrayMC->At(((AliAODMCParticle*)mother)->GetMother());
                   if (!mother)
                     break;
+                 }
                 }
-                
                 if (mother)
                 {
                   Int_t pdgCode = ((AliAODMCParticle*)mother)->GetPdgCode();
@@ -544,8 +638,9 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
                 // find the primary mother
                 AliMCParticle* mother = (AliMCParticle*) part;
 //             Printf("");
-                while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
-                {
+                if(fCheckMotherPDG) {
+                 while (!mcEvent->IsPhysicalPrimary(mother->GetLabel()))
+                  {
 //               Printf("pdg = %d; mother = %d", mother->PdgCode(), mother->GetMother());
                   if (mother->GetMother() < 0)
                   {
@@ -556,8 +651,8 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
                   mother = (AliMCParticle*) mcEvent->GetTrack(mother->GetMother());
                   if (!mother)
                     break;
+                  }
                 }
-                
                 if (mother)
                 {
                   Int_t pdgCode = mother->PdgCode();
@@ -595,11 +690,54 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
   }else if (obj->InheritsFrom("AliAODEvent")){ // RECO AOD TRACKS
        AliAODEvent *aodEvent = static_cast<AliAODEvent*>(obj);
         part = aodEvent->GetTrack(ipart);
+       
        // track selection cuts
        if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) ) return 0; 
-       //if ( !(((AliAODTrack*)part)->TestFilterBit(fFilterBit)) && !(((AliAODTrack*)part)->TestFilterBit(32)) ) return 0; 
-       // only primary candidates
-       //if ( ((AliAODTrack*)part)->IsPrimaryCandidate() )return 0;
+       if (fTrackStatus != 0 && !CheckTrack(part)) return 0;
+       
+       // DCA XY
+       if (fDCAXYCut)
+       {
+         const AliVVertex* vertex = aodEvent->GetPrimaryVertex();
+         if (!vertex)
+           return 0;
+         
+         Double_t pos[2];
+         Double_t covar[3];
+         AliAODTrack* clone = (AliAODTrack*) part->Clone();
+         Bool_t success = clone->PropagateToDCA(vertex, aodEvent->GetHeader()->GetMagneticField(), 3, pos, covar);
+         delete clone;
+         if (!success)
+           return 0;
+
+//       Printf("%f", ((AliAODTrack*)part)->DCA());
+//       Printf("%f", pos[0]);
+         if (TMath::Abs(pos[0]) > fDCAXYCut->Eval(part->Pt()))
+           return 0;
+       }
+       
+       if (fSharedClusterCut >= 0)
+       {
+         Double_t frac = Double_t(((AliAODTrack*)part)->GetTPCnclsS()) / Double_t(((AliAODTrack*)part)->GetTPCncls());
+         if (frac > fSharedClusterCut)
+           return 0;
+       }
+       
+       if (fCrossedRowsCut >= 0)
+       {
+         if (((AliAODTrack*) part)->GetTPCNCrossedRows() < fCrossedRowsCut)
+           return 0;
+       }
+       
+       if (fFoundFractionCut >= 0)
+       {
+         UInt_t findableClusters = ((AliAODTrack*) part)->GetTPCNclsF();
+         if (findableClusters == 0)
+           return 0;
+         if (((Double_t) ((AliAODTrack*) part)->GetTPCNCrossedRows() / findableClusters) < fFoundFractionCut)
+           return 0;
+       }
+
        // eventually only hadrons
        if (fOnlyHadrons){
                Bool_t isHadron = ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kPion ||
@@ -607,16 +745,20 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
                                  ((AliAODTrack*)part)->GetMostProbablePID()==AliAODTrack::kProton;
                if (!isHadron) return 0;                                  
                }
+               
+       if (particleSpecies != -1 && fHelperPID->GetParticleSpecies((AliVTrack*) part,kTRUE) != particleSpecies) return 0;
   
   }else if (obj->InheritsFrom("AliESDEvent")){ // RECO ESD TRACKS
        AliESDEvent *esdEvent = static_cast<AliESDEvent*>(obj);
         part = esdEvent->GetTrack(ipart);
        if (!part)return 0;
+
        // track selection cuts
-       
        if (!( ApplyCuts(part)) )
-        return 0; 
+         return 0; 
        
+       if (fTrackStatus != 0 && !CheckTrack(part)) return 0;
+
        if (fFilterBit == 128 || fFilterBit == 256 || fFilterBit == 512 || fFilterBit == 1024)
        {
          // create TPC only tracks constrained to the SPD vertex
@@ -626,6 +768,8 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
          AliESDtrack* track = AliESDtrackCuts::GetTPCOnlyTrack(esdEvent, ipart);
          if(!track) return 0;
     
+//       Printf(">%f %f %f", track->Eta(), track->Phi(), track->Pt());
+         
          if(track->Pt()>0.){
            // only constrain tracks above threshold
            AliExternalTrackParam exParam;
@@ -641,8 +785,29 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
            track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
          }
          
+//       Printf(">%f %f %f\n", track->Eta(), track->Phi(), track->Pt());
+
          part = track;
        }
+       else if (fFilterBit == 2048)
+       {
+         // hybrid tracks
+         
+         // clone
+         AliESDtrack* esdTrack = new AliESDtrack(*((AliESDtrack*) part));
+//       Printf("%d %d %d %d %d", fEsdTrackCuts->IsSelected(esdTrack), fEsdTrackCutsExtra1->IsSelected(esdTrack), fEsdTrackCutsExtra2->IsSelected(esdTrack), esdTrack->HasPointOnITSLayer(0), esdTrack->HasPointOnITSLayer(1));
+         
+         if (fEsdTrackCutsExtra2->IsSelected(esdTrack))
+         {
+//         Float_t ptBefore = esdTrack->Pt();
+           // set constrained pT as default pT
+           if (!esdTrack->GetConstrainedParam())
+             return 0;
+           esdTrack->CopyFromVTrack(esdTrack->GetConstrainedParam());
+//         Printf("%f %f", ptBefore, esdTrack->Pt());
+         }
+         part = esdTrack;
+       }
        
        // eventually only hadrons
        //TO-DO
@@ -653,6 +818,8 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
                if (!isHadron) return 0;                                  
                }
        */      
+       if (particleSpecies != -1 && fHelperPID->GetParticleSpecies((AliVTrack*) part,kTRUE) != particleSpecies) return 0; // If it is -1 you take all the particles
+
   }else {
        if (fDebug > 1) AliFatal(" Analysis type not defined !!! ");
        return 0;
@@ -661,6 +828,7 @@ AliVParticle*  AliAnalyseLeadingTrackUE::ParticleWithCuts(TObject* obj, Int_t ip
   // only charged
   if (!part->Charge())return 0;
   
+  part->SetUniqueID(fEventCounter * 100000 + ipart);
   return part;
 }
 
@@ -748,7 +916,7 @@ TObjArray*  AliAnalyseLeadingTrackUE::SortRegions(const AliVParticle* leading, T
        TVector3 partVect(part->Px(), part->Py(), part->Pz());
  
        Int_t region = 0;
-       if( TMath::Abs(partVect.Eta()) > fTrackEtaCut ) continue;
+       if( TMath::Abs(partVect.Eta()) > fTrackEtaCut || TMath::Abs(partVect.Eta()) < fTrackEtaCutMin) continue;
        // transverse regions
        if (leadVect.DeltaPhi(partVect) < -k60rad && leadVect.DeltaPhi(partVect) > -k120rad )region = -1; //left
        if (leadVect.DeltaPhi(partVect) > k60rad && leadVect.DeltaPhi(partVect) < k120rad ) region = 1;   //right
@@ -819,7 +987,7 @@ Bool_t  AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntra
                if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
 
                // Select a quality vertex by number of tracks?
-               if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
+               if( nTracksPrim < ntracks || TMath::Abs(zVertex) >= zed ) {
                        if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
                        return kFALSE;
                        }
@@ -835,7 +1003,7 @@ Bool_t  AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntra
 
   if (obj->InheritsFrom("AliMCEvent"))
   { 
-    if (TMath::Abs(((AliMCEvent*) obj)->GetPrimaryVertex()->GetZ()) > zed)
+    if (TMath::Abs(((AliMCEvent*) obj)->GetPrimaryVertex()->GetZ()) >= zed)
     {
       if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
       return kFALSE;
@@ -844,7 +1012,7 @@ Bool_t  AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntra
 
   if (obj->InheritsFrom("AliAODMCHeader"))
   { 
-    if (TMath::Abs(((AliAODMCHeader*) obj)->GetVtxZ()) > zed)
+    if (TMath::Abs(((AliAODMCHeader*) obj)->GetVtxZ()) >= zed)
     {
       if (fDebug > 1) AliInfo(" Primary-vertex Selection: event (based on MC) REJECTED ...");
       return kFALSE;
@@ -863,7 +1031,7 @@ Bool_t  AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntra
                if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return kFALSE;
 
                // Select a quality vertex by number of tracks?
-               if( nTracksPrim < ntracks || TMath::Abs(zVertex) > zed ) {
+               if( nTracksPrim < ntracks || TMath::Abs(zVertex) >= zed ) {
                        if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
                        return kFALSE;
                        }
@@ -879,3 +1047,15 @@ Bool_t  AliAnalyseLeadingTrackUE::VertexSelection(const TObject* obj, Int_t ntra
        
   return kTRUE;
 }
+
+//____________________________________________________________________
+
+Bool_t AliAnalyseLeadingTrackUE::CheckTrack(AliVParticle * part)
+{
+  // check if the track status flags are set
+  
+  UInt_t status=((AliVTrack*)part)->GetStatus();
+  if ((status & fTrackStatus) == fTrackStatus)
+    return kTRUE;
+  return kFALSE;
+}