]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG3/vertexingHF/AliAnalysisVertexingHF.cxx
Ref to the 2Prong moved from AliAODRecoCascadeHF to AliAODVertex
[u/mrichter/AliRoot.git] / PWG3 / vertexingHF / AliAnalysisVertexingHF.cxx
index e986f8923629f90999d12ceda35b46b12aefe922..a81cdd8b5a521ff4201d7b0bf7797167af5a4dac 100644 (file)
 
 //----------------------------------------------------------------------------
 //    Implementation of the heavy-flavour vertexing analysis class
-// Candidates are store as objects deriving from AliAODRecoDecay.
-// An example of usage can be found in the macro AliVertexingHFTest.C.
-// Can be used as a task of AliAnalysisManager by means of the interface
-// classes AliAnalysisTaskSEVertexingHF or AliAnalysisTaskVertexingHF. 
+// Candidates are stored in the AOD as objects deriving from AliAODRecoDecay.
+// To be used as a task of AliAnalysisManager by means of the interface
+// class AliAnalysisTaskSEVertexingHF. 
+// An example of usage in the macro AliAnalysisTaskSEVertexingHFTest.C.
 //
-//  Origin: E.Bruna, G.E.Bruno, A.Dainese, F.Prino, R.Romita
+//  Origin: E.Bruna, G.E.Bruno, A.Dainese, F.Prino, R.Romita, X.M.Zhang
 //  Contact: andrea.dainese@lnl.infn.it
 //----------------------------------------------------------------------------
-#include <TTree.h>
 #include <TFile.h>
 #include <TDatabasePDG.h>
 #include <TString.h>
-#include "AliESDEvent.h"
+#include "AliLog.h"
+#include "AliVEvent.h"
+#include "AliVVertex.h"
+#include "AliVTrack.h"
 #include "AliVertexerTracks.h"
-#include "AliKFParticle.h"
+#include "AliKFVertex.h"
+#include "AliESDEvent.h"
 #include "AliESDVertex.h"
+#include "AliExternalTrackParam.h"
+#include "AliNeutralTrackParam.h"
+#include "AliESDtrack.h"
+#include "AliESDtrackCuts.h"
 #include "AliAODEvent.h"
 #include "AliAODRecoDecay.h"
 #include "AliAODRecoDecayHF.h"
 #include "AliAODRecoDecayHF2Prong.h"
 #include "AliAODRecoDecayHF3Prong.h"
 #include "AliAODRecoDecayHF4Prong.h"
+#include "AliAODRecoCascadeHF.h"
+#include "AliAnalysisFilter.h"
 #include "AliAnalysisVertexingHF.h"
 
 ClassImp(AliAnalysisVertexingHF)
 
 //----------------------------------------------------------------------------
 AliAnalysisVertexingHF::AliAnalysisVertexingHF():
+fInputAOD(kFALSE),
+fAODMap(0),
 fBzkG(0.),
 fSecVtxWithKF(kFALSE),
-fUseTRef(kFALSE),
 fRecoPrimVtxSkippingTrks(kFALSE),
 fRmTrksFromPrimVtx(kFALSE),
 fV1(0x0),
-fDebug(0),
 fD0toKpi(kTRUE),
 fJPSItoEle(kTRUE),
 f3Prong(kTRUE),
 f4Prong(kTRUE),
-fITSrefit(kFALSE),
-fBothSPD(kTRUE),
-fMinITSCls(5),
-fMinPtCut(0.),
-fMind0rphiCut(0.)
+fDstar(kTRUE),
+fTrackFilter(0x0),
+fTrackFilterSoftPi(0x0)
 {
   // Default constructor
 
@@ -67,26 +74,26 @@ fMind0rphiCut(0.)
   SetDplusCuts();
   SetDsCuts();
   SetLcCuts();
+  SetDstarCuts();
+
 }
 //--------------------------------------------------------------------------
 AliAnalysisVertexingHF::AliAnalysisVertexingHF(const AliAnalysisVertexingHF &source) : 
 TNamed(source),
+fInputAOD(source.fInputAOD),
+fAODMap(source.fAODMap),
 fBzkG(source.fBzkG),
 fSecVtxWithKF(source.fSecVtxWithKF),
-fUseTRef(source.fUseTRef),
 fRecoPrimVtxSkippingTrks(source.fRecoPrimVtxSkippingTrks),
 fRmTrksFromPrimVtx(source.fRmTrksFromPrimVtx),
 fV1(source.fV1),
-fDebug(source.fDebug),
 fD0toKpi(source.fD0toKpi),
 fJPSItoEle(source.fJPSItoEle),
 f3Prong(source.f3Prong),
 f4Prong(source.f4Prong),
-fITSrefit(source.fITSrefit),
-fBothSPD(source.fBothSPD),
-fMinITSCls(source.fMinITSCls),
-fMinPtCut(source.fMinPtCut),
-fMind0rphiCut(source.fMind0rphiCut)
+fDstar(source.fDstar),
+fTrackFilter(source.fTrackFilter),
+fTrackFilterSoftPi(source.fTrackFilterSoftPi)
 {
   //
   // Copy constructor
@@ -94,8 +101,9 @@ fMind0rphiCut(source.fMind0rphiCut)
   for(Int_t i=0; i<9; i++)  fD0toKpiCuts[i]=source.fD0toKpiCuts[i];
   for(Int_t i=0; i<9; i++)  fBtoJPSICuts[i]=source.fBtoJPSICuts[i];
   for(Int_t i=0; i<12; i++) fDplusCuts[i]=source.fDplusCuts[i];
-  for(Int_t i=0; i<13; i++)  fDsCuts[i]=source.fDsCuts[i];
-  for(Int_t i=0; i<12; i++)  fLcCuts[i]=source.fLcCuts[i];
+  for(Int_t i=0; i<13; i++) fDsCuts[i]=source.fDsCuts[i];
+  for(Int_t i=0; i<12; i++) fLcCuts[i]=source.fLcCuts[i];
+  for(Int_t i=0; i<5; i++)  fDstarCuts[i]=source.fDstarCuts[i];
 }
 //--------------------------------------------------------------------------
 AliAnalysisVertexingHF &AliAnalysisVertexingHF::operator=(const AliAnalysisVertexingHF &source)
@@ -104,28 +112,26 @@ AliAnalysisVertexingHF &AliAnalysisVertexingHF::operator=(const AliAnalysisVerte
   // assignment operator
   //
   if(&source == this) return *this;
+  fInputAOD = source.fInputAOD;
   fBzkG = source.fBzkG;
   fSecVtxWithKF = source.fSecVtxWithKF;
-  fUseTRef = source.fUseTRef;
   fRecoPrimVtxSkippingTrks = source.fRecoPrimVtxSkippingTrks;
   fRmTrksFromPrimVtx = source.fRmTrksFromPrimVtx;
   fV1 = source.fV1;
-  fDebug = source.fDebug;
   fD0toKpi = source.fD0toKpi;
   fJPSItoEle = source.fJPSItoEle;
   f3Prong = source.f3Prong;
   f4Prong = source.f4Prong;
-  fITSrefit = source.fITSrefit;
-  fBothSPD = source.fBothSPD;
-  fMinITSCls = source.fMinITSCls;
-  fMinPtCut = source.fMinPtCut;
-  fMind0rphiCut = source.fMind0rphiCut;
+  fDstar = source.fDstar;
+  fTrackFilter = source.fTrackFilter;
+  fTrackFilterSoftPi = source.fTrackFilterSoftPi;
 
   for(Int_t i=0; i<9; i++)  fD0toKpiCuts[i]=source.fD0toKpiCuts[i];
   for(Int_t i=0; i<9; i++)  fBtoJPSICuts[i]=source.fBtoJPSICuts[i];
   for(Int_t i=0; i<12; i++) fDplusCuts[i]=source.fDplusCuts[i];
-  for(Int_t i=0; i<13; i++)  fDsCuts[i]=source.fDsCuts[i];
-  for(Int_t i=0; i<12; i++)  fLcCuts[i]=source.fLcCuts[i];
+  for(Int_t i=0; i<13; i++) fDsCuts[i]=source.fDsCuts[i];
+  for(Int_t i=0; i<12; i++) fLcCuts[i]=source.fLcCuts[i];
+  for(Int_t i=0; i<5; i++)  fDstarCuts[i]=source.fDstarCuts[i];
 
   return *this;
 }
@@ -133,24 +139,31 @@ AliAnalysisVertexingHF &AliAnalysisVertexingHF::operator=(const AliAnalysisVerte
 AliAnalysisVertexingHF::~AliAnalysisVertexingHF() {
   // Destructor
   if(fV1) { delete fV1; fV1=0; }
+  if(fTrackFilter) { delete fTrackFilter; fTrackFilter=0; }
+  if(fTrackFilterSoftPi) { delete fTrackFilterSoftPi; fTrackFilterSoftPi=0; }
 }
 //----------------------------------------------------------------------------
-void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
-                                       TClonesArray *aodVerticesHFTClArr,
-                                       TClonesArray *aodD0toKpiTClArr,
-                                       TClonesArray *aodJPSItoEleTClArr,
-                                       TClonesArray *aodCharm3ProngTClArr,
-                                       TClonesArray *aodCharm4ProngTClArr)
+void AliAnalysisVertexingHF::FindCandidates(AliVEvent *event,
+                                           TClonesArray *aodVerticesHFTClArr,
+                                           TClonesArray *aodD0toKpiTClArr,
+                                           TClonesArray *aodJPSItoEleTClArr,
+                                           TClonesArray *aodCharm3ProngTClArr,
+                                           TClonesArray *aodCharm4ProngTClArr,
+                                           TClonesArray *aodDstarTClArr)
 {
   // Find heavy-flavour vertex candidates
-  // Input:  ESD
+  // Input:  ESD or AOD
   // Output: AOD (additional branches added)
 
+
+  TString evtype = event->IsA()->GetName();
+  fInputAOD = ((evtype=="AliAODEvent") ? kTRUE : kFALSE);
+
   if(!aodVerticesHFTClArr) {
     printf("ERROR: no aodVerticesHFTClArr");
     return;
   }
-  if(fD0toKpi && !aodD0toKpiTClArr) {
+  if((fD0toKpi || fDstar) && !aodD0toKpiTClArr) {
     printf("ERROR: no aodD0toKpiTClArr");
     return;
   }
@@ -166,13 +179,17 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
     printf("ERROR: no aodCharm4ProngTClArr");
     return;
   }
+  if(fDstar && !aodDstarTClArr) {
+    printf("ERROR: no aodDstarTClArr");
+    return;
+  }
 
   // delete candidates from previous event and create references
-  Int_t iVerticesHF=0,iD0toKpi=0,iJPSItoEle=0,i3Prong=0,i4Prong=0;
+  Int_t iVerticesHF=0,iD0toKpi=0,iJPSItoEle=0,i3Prong=0,i4Prong=0,iDstar=0;
   aodVerticesHFTClArr->Delete();
   iVerticesHF = aodVerticesHFTClArr->GetEntriesFast();
   TClonesArray &verticesHFRef = *aodVerticesHFTClArr;
-  if(fD0toKpi)   {
+  if(fD0toKpi || fDstar)   {
     aodD0toKpiTClArr->Delete();
     iD0toKpi = aodD0toKpiTClArr->GetEntriesFast();
   }
@@ -188,122 +205,185 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
     aodCharm4ProngTClArr->Delete();
     i4Prong = aodCharm4ProngTClArr->GetEntriesFast();
   }
-  TClonesArray &aodD0toKpiRef     = *aodD0toKpiTClArr;
-  TClonesArray &aodJPSItoEleRef   = *aodJPSItoEleTClArr;
-  TClonesArray &aodCharm3ProngRef = *aodCharm3ProngTClArr;
-  TClonesArray &aodCharm4ProngRef = *aodCharm4ProngTClArr;
+  if(fDstar) {
+    aodDstarTClArr->Delete();
+    iDstar = aodDstarTClArr->GetEntriesFast();
+  }
+  TClonesArray &aodD0toKpiRef      = *aodD0toKpiTClArr;
+  TClonesArray &aodJPSItoEleRef    = *aodJPSItoEleTClArr;
+  TClonesArray &aodCharm3ProngRef  = *aodCharm3ProngTClArr;
+  TClonesArray &aodCharm4ProngRef  = *aodCharm4ProngTClArr;
+  TClonesArray &aodDstarRef        = *aodDstarTClArr;
   
 
-  AliAODRecoDecayHF2Prong *io2Prong = 0;
-  AliAODRecoDecayHF3Prong *io3Prong = 0;
-  AliAODRecoDecayHF4Prong *io4Prong = 0;
+  AliAODRecoDecayHF2Prong *io2Prong  = 0;
+  AliAODRecoDecayHF3Prong *io3Prong  = 0;
+  AliAODRecoDecayHF4Prong *io4Prong  = 0;
+  AliAODRecoCascadeHF     *ioCascade = 0;
 
-  Int_t    iTrkP1,iTrkP2,iTrkN1,iTrkN2,trkEntries;
-  Int_t    nTrksP=0,nTrksN=0;
-  Double_t xdummy,ydummy,dcap1n1,dcap1n2,dcap2n1,dcap1p2,dcan1n2;
+  Int_t    iTrkP1,iTrkP2,iTrkN1,iTrkN2,iTrkSoftPi,trkEntries;
+  Double_t xdummy,ydummy,dcap1n1,dcap1n2,dcap2n1,dcap1p2,dcan1n2,dcaCasc;
   Bool_t   okD0=kFALSE,okJPSI=kFALSE,ok3Prong=kFALSE,ok4Prong=kFALSE;
+  Bool_t   okDstar=kFALSE,okD0fromDstar=kFALSE;
   AliESDtrack *postrack1 = 0;
   AliESDtrack *postrack2 = 0;
   AliESDtrack *negtrack1 = 0;
   AliESDtrack *negtrack2 = 0;
+  AliESDtrack *trackPi   = 0;
   Double_t dcaMax = fD0toKpiCuts[1];
   if(dcaMax < fBtoJPSICuts[1]) dcaMax=fBtoJPSICuts[1];
   if(dcaMax < fDplusCuts[11])  dcaMax=fDplusCuts[11];
-  if(fDebug) printf(" dca cut set to %f cm\n",dcaMax);
+  AliDebug(2,Form(" dca cut set to %f cm",dcaMax));
 
-  //------- SINGLE EVENT ANALYSIS ---------------------------------
-  //
-  Int_t ev = (Int_t)esd->GetEventNumberInFile();
-  printf("--- Finding candidates in event %d\n",ev);
-    
 
-  // get Bz from ESD
-  fBzkG = (Double_t)esd->GetMagneticField(); 
+  // get Bz
+  fBzkG = (Double_t)event->GetMagneticField(); 
+
+  trkEntries = (Int_t)event->GetNumberOfTracks();
+  AliDebug(1,Form(" Number of tracks: %d",trkEntries));
 
-  trkEntries = (Int_t)esd->GetNumberOfTracks();
-  printf(" Number of tracks: %d\n",trkEntries);
+  if(trkEntries<2) {
+    AliDebug(1,Form(" Not enough tracks: %d",trkEntries));
+    return;
+  }
     
-  if(trkEntries<2 || !esd->GetPrimaryVertex()) {
+  const AliVVertex *primary = event->GetPrimaryVertex();
+  if(!primary) {
+    AliDebug(1," No primary vertex from tracks");
+    return;
+  }
+  TString primTitle = primary->GetTitle();
+  if(!primTitle.Contains("VertexerTracks")) {
+    AliDebug(1," No primary vertex from tracks");
     return;
   }
 
-  // retrieve primary vertex from the AliESDEvent
-  AliESDVertex copy(*(esd->GetPrimaryVertex()));
-  SetPrimaryVertex(&copy);
+  // call function that applies sigle-track selection,
+  // for displaced tracks and soft pions (both charges) for D*,
+  // and retrieves primary vertex
+  TObjArray seleTrksArray(trkEntries);
+  UChar_t  *seleFlags = new UChar_t[trkEntries]; // bit 0: displaced, bit 1: softpi
+  Int_t     nSeleTrks=0;
+  SelectTracksAndCopyVertex(event,seleTrksArray,nSeleTrks,seleFlags);
     
-  // call function which applies sigle-track selection and
-  // separates positives and negatives
-  TObjArray trksP(trkEntries/2);
-  TObjArray trksN(trkEntries/2);
-  SelectTracks(esd,trksP,nTrksP,trksN,nTrksN);
+  AliDebug(1,Form(" Selected tracks: %d",nSeleTrks));
     
-  printf(" Pos. tracks: %d    Neg. tracks: %d\n",nTrksP,nTrksN);
-    
-  TObjArray *twoTrackArray1  = new TObjArray(2);
-  TObjArray *twoTrackArray2  = new TObjArray(2);
-  TObjArray *threeTrackArray = new TObjArray(3);
-  TObjArray *fourTrackArray  = new TObjArray(4);
+  TObjArray *twoTrackArray1    = new TObjArray(2);
+  TObjArray *twoTrackArray2    = new TObjArray(2);
+  TObjArray *twoTrackArrayCasc = new TObjArray(2);
+  TObjArray *threeTrackArray   = new TObjArray(3);
+  TObjArray *fourTrackArray    = new TObjArray(4);
   
+  Double_t dispersion;
+
+  AliAODRecoDecayHF   *rd = 0;
+  AliAODRecoCascadeHF *rc = 0;
+
   // LOOP ON  POSITIVE  TRACKS
-  for(iTrkP1=0; iTrkP1<nTrksP; iTrkP1++) {
-    if(fDebug && iTrkP1%1==0) printf("  Processing positive track number %d of %d\n",iTrkP1,nTrksP);  
+  for(iTrkP1=0; iTrkP1<nSeleTrks; iTrkP1++) {
+    if(iTrkP1%1==0) AliDebug(1,Form("  1st loop on pos: track number %d of %d",iTrkP1,nSeleTrks));  
     // get track from tracks array
-    postrack1 = (AliESDtrack*)trksP.UncheckedAt(iTrkP1);
-      
+    postrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP1);
+    if(postrack1->Charge()<0 || !TESTBIT(seleFlags[iTrkP1],kBitDispl)) continue;
     // LOOP ON  NEGATIVE  TRACKS
-    for(iTrkN1=0; iTrkN1<nTrksN; iTrkN1++) {
-      if(fDebug && iTrkN1%1==0) printf("    Processing negative track number %d of %d\n",iTrkN1,nTrksN);  
+    for(iTrkN1=0; iTrkN1<nSeleTrks; iTrkN1++) {
+      if(iTrkN1==iTrkP1) continue;
+      if(iTrkN1%1==0) AliDebug(1,Form("    1st loop on neg: track number %d of %d",iTrkN1,nSeleTrks));  
       // get track from tracks array
-      negtrack1 = (AliESDtrack*)trksN.UncheckedAt(iTrkN1);
+      negtrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN1);
+      if(negtrack1->Charge()>0 || !TESTBIT(seleFlags[iTrkN1],kBitDispl)) continue;
+      // back to primary vertex
+      postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
+      negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
       // DCA between the two tracks
       dcap1n1 = postrack1->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
       if(dcap1n1>dcaMax) { negtrack1=0; continue; }
       // Vertexing
       twoTrackArray1->AddAt(postrack1,0);
       twoTrackArray1->AddAt(negtrack1,1);
-      AliESDVertex *vertexp1n1 = ReconstructSecondaryVertex(twoTrackArray1);
+      AliAODVertex *vertexp1n1 = ReconstructSecondaryVertex(twoTrackArray1,dispersion);
       if(!vertexp1n1) { 
        twoTrackArray1->Clear();
        negtrack1=0; 
        continue; 
       }
-      if(fD0toKpi || fJPSItoEle) { 
-       io2Prong = Make2Prong(twoTrackArray1,esd,vertexp1n1,dcap1n1,okD0,okJPSI);
-       if(okD0 || okJPSI) {
-         if(fUseTRef) {
-           AliAODVertex *v = new(verticesHFRef[iVerticesHF++]) 
-             AliAODVertex(*(io2Prong->GetOwnSecondaryVtx()));
-           v->SetType(AliAODVertex::kUndef); // to be changed
-           Double_t px[2]={io2Prong->PxProng(0),io2Prong->PxProng(1)};
-           Double_t py[2]={io2Prong->PyProng(0),io2Prong->PyProng(1)};
-           Double_t pz[2]={io2Prong->PzProng(0),io2Prong->PzProng(1)};
-           Double_t d0[2]={io2Prong->Getd0Prong(0),io2Prong->Getd0Prong(1)};
-           Double_t d0err[2]={io2Prong->Getd0errProng(0),io2Prong->Getd0errProng(1)};
-           UShort_t id[2]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack1->GetID()};
-           if(okD0) {  
-             AliAODRecoDecayHF2Prong *rd=new(aodD0toKpiRef[iD0toKpi++]) 
-               AliAODRecoDecayHF2Prong(v,px,py,pz,d0,d0err,dcap1n1);
-             if(fRecoPrimVtxSkippingTrks || fRmTrksFromPrimVtx) rd->SetOwnPrimaryVtx(io2Prong->GetOwnPrimaryVtx());
-             rd->SetProngIDs(2,id);
-             v->SetParent(rd);
+      if(fD0toKpi || fJPSItoEle || fDstar) { 
+       io2Prong = Make2Prong(twoTrackArray1,event,vertexp1n1,dcap1n1,okD0,okJPSI,okD0fromDstar);
+       if((fD0toKpi && okD0) || (fJPSItoEle && okJPSI)) {
+         // add the vertex and the decay to the AOD
+         AliAODVertex *v2Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
+         if(fInputAOD) AddDaughterRefs(v2Prong,event,twoTrackArray1);
+         if(okD0) {  
+           rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
+           rd->SetSecondaryVtx(v2Prong);
+           v2Prong->SetParent(rd);
+         }
+         if(okJPSI) {
+           rd = new(aodJPSItoEleRef[iJPSItoEle++])AliAODRecoDecayHF2Prong(*io2Prong);
+           rd->SetSecondaryVtx(v2Prong);
+           if(!okD0) v2Prong->SetParent(rd); // it cannot have two mothers ...
+         }
+       }
+       if(fDstar && okD0fromDstar) {
+         if(fInputAOD) { // write references in io2Prong
+           AddDaughterRefs(vertexp1n1,event,twoTrackArray1);
+           io2Prong->SetSecondaryVtx(vertexp1n1);
+         }
+         // create a track from the D0
+         AliNeutralTrackParam *trackD0 = new AliNeutralTrackParam(io2Prong);
+         // LOOP ON TRACKS THAT PASSED THE SOFT PION CUTS
+         for(iTrkSoftPi=0; iTrkSoftPi<nSeleTrks; iTrkSoftPi++) {
+           if(iTrkSoftPi==iTrkP1 || iTrkSoftPi==iTrkN1) continue;
+           if(!TESTBIT(seleFlags[iTrkSoftPi],kBitSoftPi)) continue;
+           if(iTrkSoftPi%1==0) AliDebug(1,Form("    1st loop on pi_s: track number %d of %d",iTrkSoftPi,nSeleTrks));  
+           // get track from tracks array
+           trackPi = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkSoftPi);
+
+           trackPi->PropagateToDCA(fV1,fBzkG,kVeryBig);
+           trackD0->PropagateToDCA(fV1,fBzkG,kVeryBig);
+           // DCA between the two tracks
+           dcaCasc = trackPi->GetDCA(trackD0,fBzkG,xdummy,ydummy);
+           // Vertexing
+           twoTrackArrayCasc->AddAt(trackPi,0);
+           twoTrackArrayCasc->AddAt(trackD0,1);
+           AliAODVertex *vertexCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
+           if(!vertexCasc) { 
+             twoTrackArrayCasc->Clear();
+             trackPi=0; 
+             continue; 
            }
-           if(okJPSI) {
-             AliAODRecoDecayHF2Prong *rd=new(aodJPSItoEleRef[iJPSItoEle++]) 
-               AliAODRecoDecayHF2Prong(v,px,py,pz,d0,d0err,dcap1n1);
-             if(fRecoPrimVtxSkippingTrks || fRmTrksFromPrimVtx) rd->SetOwnPrimaryVtx(io2Prong->GetOwnPrimaryVtx());
-             rd->SetProngIDs(2,id);
-             if(!okD0) v->SetParent(rd); // do something better here...
+            ioCascade = MakeCascade(twoTrackArrayCasc,event,vertexCasc,io2Prong,dcaCasc,okDstar);
+            if(okDstar) {
+             if(!okD0) {
+               // add the D0 to the AOD (if not already done)
+               AliAODVertex *v2Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
+               if(fInputAOD) AddDaughterRefs(v2Prong,event,twoTrackArray1);
+               rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
+               rd->SetSecondaryVtx(v2Prong);
+               v2Prong->SetParent(rd);
+               okD0=kTRUE; // this is done to add it only once
+             }
+             // add the vertex and the cascade to the AOD
+             AliAODVertex *vCasc = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexCasc); 
+             if(fInputAOD) {
+               AddDaughterRefs(vCasc,event,twoTrackArrayCasc); // add the pion
+             } else {
+               vCasc->AddDaughter(rd); // just to fill ref #0 
+             }
+             vCasc->AddDaughter(rd); // add the D0 (in ref #1)
+             rc = new(aodDstarRef[iDstar++])AliAODRecoCascadeHF(*ioCascade);
+             rc->SetSecondaryVtx(vCasc);
+             vCasc->SetParent(rc);
            }
-           //printf("DCA: %f\n",rd->GetDCA());
-         } else {
-           if(okD0)   new(aodD0toKpiRef[iD0toKpi++]) AliAODRecoDecayHF2Prong(*io2Prong);
-           if(okJPSI) new(aodJPSItoEleRef[iJPSItoEle++]) AliAODRecoDecayHF2Prong(*io2Prong);
-         }
+           twoTrackArrayCasc->Clear();
+           trackPi=0; 
+           ioCascade=NULL;
+           delete vertexCasc;
+         } // end loop on soft pi tracks
+         if(trackD0) {delete trackD0; trackD0=NULL;}
        }
-       //delete io2Prong;
        io2Prong=NULL;
-      }
-      
+      }      
       twoTrackArray1->Clear(); 
       if(!f3Prong && !f4Prong)  { 
        negtrack1=0; 
@@ -313,9 +393,17 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
 
        
       // 2nd LOOP  ON  POSITIVE  TRACKS 
-      for(iTrkP2=iTrkP1+1; iTrkP2<nTrksP; iTrkP2++) {
+      for(iTrkP2=iTrkP1+1; iTrkP2<nSeleTrks; iTrkP2++) {
+       if(iTrkP2==iTrkP1 || iTrkP2==iTrkN1) continue;
+       if(iTrkP2%1==0) AliDebug(1,Form("    2nd loop on pos: track number %d of %d",iTrkP2,nSeleTrks));  
        // get track from tracks array
-       postrack2 = (AliESDtrack*)trksP.UncheckedAt(iTrkP2);
+       postrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP2);
+       if(postrack2->Charge()<0 || !TESTBIT(seleFlags[iTrkP2],kBitDispl)) continue;
+       // back to primary vertex
+       postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
+       postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
+       negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
+       //printf("********** %d %d %d\n",postrack1->GetID(),postrack2->GetID(),negtrack1->GetID());
        dcap2n1 = postrack2->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
        if(dcap2n1>dcaMax) { postrack2=0; continue; }
        dcap1p2 = postrack2->GetDCA(postrack1,fBzkG,xdummy,ydummy);
@@ -324,7 +412,7 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
        // Vertexing
        twoTrackArray2->AddAt(postrack2,0);
        twoTrackArray2->AddAt(negtrack1,1);
-       AliESDVertex *vertexp2n1 = ReconstructSecondaryVertex(twoTrackArray2);
+       AliAODVertex *vertexp2n1 = ReconstructSecondaryVertex(twoTrackArray2,dispersion);
        if(!vertexp2n1) { 
          twoTrackArray2->Clear();
          postrack2=0; 
@@ -334,35 +422,30 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
          threeTrackArray->AddAt(postrack1,0);
          threeTrackArray->AddAt(negtrack1,1);
          threeTrackArray->AddAt(postrack2,2);
-         io3Prong = Make3Prong(threeTrackArray,esd,vertexp1n1,vertexp2n1,dcap1n1,dcap2n1,dcap1p2,ok3Prong);
+         AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
+         io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,vertexp2n1,dcap1n1,dcap2n1,dcap1p2,ok3Prong);
          if(ok3Prong) {
-           if(fUseTRef) {
-             AliAODVertex *v = new(verticesHFRef[iVerticesHF++]) 
-               AliAODVertex(*(io3Prong->GetOwnSecondaryVtx()));
-             v->SetType(AliAODVertex::kUndef);
-             Double_t px[3]={io3Prong->PxProng(0),io3Prong->PxProng(1),io3Prong->PxProng(2)};
-             Double_t py[3]={io3Prong->PyProng(0),io3Prong->PyProng(1),io3Prong->PyProng(2)};
-             Double_t pz[3]={io3Prong->PzProng(0),io3Prong->PzProng(1),io3Prong->PzProng(2)};
-             Double_t d0[3]={io3Prong->Getd0Prong(0),io3Prong->Getd0Prong(1),io3Prong->Getd0Prong(2)};
-             Double_t d0err[3]={io3Prong->Getd0errProng(0),io3Prong->Getd0errProng(1),io3Prong->Getd0errProng(2)};
-             Double_t dcas[3]={io3Prong->GetDCA(0),io3Prong->GetDCA(1),io3Prong->GetDCA(2)};
-             UShort_t id[3]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack1->GetID(),(UShort_t)postrack2->GetID()};
-             AliAODRecoDecayHF3Prong *rd=new(aodCharm3ProngRef[i3Prong++]) 
-               AliAODRecoDecayHF3Prong(v,px,py,pz,d0,d0err,dcas,io3Prong->GetSigmaVert(),io3Prong->GetDist12toPrim(),io3Prong->GetDist23toPrim(),io3Prong->GetCharge());
-             if(fRecoPrimVtxSkippingTrks || fRmTrksFromPrimVtx) rd->SetOwnPrimaryVtx(io3Prong->GetOwnPrimaryVtx());
-             rd->SetProngIDs(3,id);
-             v->SetParent(rd);
-           } else {
-             new(aodD0toKpiRef[i3Prong++]) AliAODRecoDecayHF3Prong(*io3Prong);
-           }
+           AliAODVertex *v3Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
+           if(fInputAOD) AddDaughterRefs(v3Prong,event,threeTrackArray);
+           rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
+           rd->SetSecondaryVtx(v3Prong);
+           v3Prong->SetParent(rd);
          }
-         if(io3Prong) { /*delete io3Prong;*/ io3Prong=NULL; } 
+         if(io3Prong) io3Prong=NULL; 
        }
        if(f4Prong) {
          // 3rd LOOP  ON  NEGATIVE  TRACKS (for 4 prong) 
-         for(iTrkN2=iTrkN1+1; iTrkN2<nTrksN; iTrkN2++) {
+         for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
+           if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
+           if(iTrkN2%1==0) AliDebug(1,Form("    3rd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));  
            // get track from tracks array
-           negtrack2 = (AliESDtrack*)trksN.UncheckedAt(iTrkN2);
+           negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
+           if(negtrack2->Charge()>0 || !TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
+           // back to primary vertex
+           postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
+           postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
+           negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
+           negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
            dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
            if(dcap1n2>dcaMax) { negtrack2=0; continue; }
            // Vertexing
@@ -370,34 +453,16 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
            fourTrackArray->AddAt(negtrack1,1);
            fourTrackArray->AddAt(postrack2,2);
            fourTrackArray->AddAt(negtrack2,3);
-           io4Prong = Make4Prong(fourTrackArray,esd,vertexp1n1,vertexp2n1,dcap1n1,dcap1n2,dcap2n1,ok4Prong);
+           AliAODVertex* secVert4PrAOD = ReconstructSecondaryVertex(fourTrackArray,dispersion);
+           io4Prong = Make4Prong(fourTrackArray,event,secVert4PrAOD,vertexp1n1,vertexp2n1,dcap1n1,dcap1n2,dcap2n1,ok4Prong);
            if(ok4Prong) {
-             if(fUseTRef) {
-               AliAODVertex *v = new(verticesHFRef[iVerticesHF++]) 
-                 AliAODVertex(*(io4Prong->GetOwnSecondaryVtx()));
-               v->SetType(AliAODVertex::kUndef);
-               Double_t px[4]={io4Prong->PxProng(0),io4Prong->PxProng(1),
-                               io4Prong->PxProng(2),io4Prong->PxProng(3)};
-               Double_t py[4]={io4Prong->PyProng(0),io4Prong->PyProng(1),
-                               io4Prong->PyProng(2),io4Prong->PyProng(3)};
-               Double_t pz[4]={io4Prong->PzProng(0),io4Prong->PzProng(1),
-                               io4Prong->PzProng(2),io4Prong->PzProng(3)};
-               Double_t d0[4]={io4Prong->Getd0Prong(0),io4Prong->Getd0Prong(1),
-                               io4Prong->Getd0Prong(2),io4Prong->Getd0Prong(3)};
-               Double_t d0err[4]={io4Prong->Getd0errProng(0),io4Prong->Getd0errProng(1),
-                                  io4Prong->Getd0errProng(2),io4Prong->Getd0errProng(3)};
-               Double_t dcas[6]; io4Prong->GetDCAs(dcas);
-               UShort_t id[4]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack1->GetID(),(UShort_t)postrack2->GetID(),(UShort_t)negtrack2->GetID()};
-               AliAODRecoDecayHF4Prong *rd=new(aodCharm4ProngRef[i4Prong++]) 
-                 AliAODRecoDecayHF4Prong(v,px,py,pz,d0,d0err,dcas,io4Prong->GetDist12toPrim(),io4Prong->GetDist23toPrim(),io4Prong->GetDist14toPrim(),io4Prong->GetDist34toPrim(),io4Prong->GetCharge());
-               if(fRecoPrimVtxSkippingTrks || fRmTrksFromPrimVtx) rd->SetOwnPrimaryVtx(io4Prong->GetOwnPrimaryVtx());
-               rd->SetProngIDs(4,id);
-               v->SetParent(rd);
-             } else {
-               new(aodD0toKpiRef[i4Prong++]) AliAODRecoDecayHF4Prong(*io4Prong);
-             }
+             AliAODVertex *v4Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert4PrAOD);
+             if(fInputAOD) AddDaughterRefs(v4Prong,event,fourTrackArray);
+             rd = new(aodCharm4ProngRef[i4Prong++])AliAODRecoDecayHF4Prong(*io4Prong);
+             rd->SetSecondaryVtx(v4Prong);
+             v4Prong->SetParent(rd);
            }
-           if(io4Prong) { /*delete io4Prong;*/ io4Prong=NULL; } 
+           if(io4Prong) io4Prong=NULL; 
            fourTrackArray->Clear();
            negtrack2 = 0;
          } // end loop on negative tracks
@@ -408,9 +473,17 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
       twoTrackArray2->Clear();
       
       // 2nd LOOP  ON  NEGATIVE  TRACKS 
-      for(iTrkN2=iTrkN1+1; iTrkN2<nTrksN; iTrkN2++) {
+      for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
+       if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
+       if(iTrkN2%1==0) AliDebug(1,Form("    2nd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));  
        // get track from tracks array
-       negtrack2 = (AliESDtrack*)trksN.UncheckedAt(iTrkN2);
+       negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
+       if(negtrack2->Charge()>0 || !TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
+       // back to primary vertex
+       postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
+       negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
+       negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
+       //printf("********** %d %d %d\n",postrack1->GetID(),negtrack1->GetID(),negtrack2->GetID());
        dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
        if(dcap1n2>dcaMax) { negtrack2=0; continue; }
        dcan1n2 = negtrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
@@ -419,7 +492,8 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
        // Vertexing
        twoTrackArray2->AddAt(postrack1,0);
        twoTrackArray2->AddAt(negtrack2,1);
-       AliESDVertex *vertexp1n2 = ReconstructSecondaryVertex(twoTrackArray2);
+
+       AliAODVertex *vertexp1n2 = ReconstructSecondaryVertex(twoTrackArray2,dispersion);
        if(!vertexp1n2) { 
          twoTrackArray2->Clear();
          negtrack2=0; 
@@ -429,29 +503,16 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
          threeTrackArray->AddAt(negtrack1,0);
          threeTrackArray->AddAt(postrack1,1);
          threeTrackArray->AddAt(negtrack2,2);
-         io3Prong = Make3Prong(threeTrackArray,esd,vertexp1n1,vertexp1n2,dcap1n1,dcap1n2,dcan1n2,ok3Prong);
+         AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
+         io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,vertexp1n2,dcap1n1,dcap1n2,dcan1n2,ok3Prong);
          if(ok3Prong) {
-           if(fUseTRef) {
-             AliAODVertex *v = new(verticesHFRef[iVerticesHF++]) 
-               AliAODVertex(*(io3Prong->GetOwnSecondaryVtx()));
-             v->SetType(AliAODVertex::kUndef);
-             Double_t px[3]={io3Prong->PxProng(0),io3Prong->PxProng(1),io3Prong->PxProng(2)};
-             Double_t py[3]={io3Prong->PyProng(0),io3Prong->PyProng(1),io3Prong->PyProng(2)};
-             Double_t pz[3]={io3Prong->PzProng(0),io3Prong->PzProng(1),io3Prong->PzProng(2)};
-             Double_t d0[3]={io3Prong->Getd0Prong(0),io3Prong->Getd0Prong(1),io3Prong->Getd0Prong(2)};
-             Double_t d0err[3]={io3Prong->Getd0errProng(0),io3Prong->Getd0errProng(1),io3Prong->Getd0errProng(2)};
-             Double_t dcas[3]={io3Prong->GetDCA(0),io3Prong->GetDCA(1),io3Prong->GetDCA(2)};
-             UShort_t id[3]={(UShort_t)negtrack1->GetID(),(UShort_t)postrack1->GetID(),(UShort_t)negtrack2->GetID()};
-             AliAODRecoDecayHF3Prong *rd=new(aodCharm3ProngRef[i3Prong++]) 
-               AliAODRecoDecayHF3Prong(v,px,py,pz,d0,d0err,dcas,io3Prong->GetSigmaVert(),io3Prong->GetDist12toPrim(),io3Prong->GetDist23toPrim(),io3Prong->GetCharge());
-             if(fRecoPrimVtxSkippingTrks || fRmTrksFromPrimVtx) rd->SetOwnPrimaryVtx(io3Prong->GetOwnPrimaryVtx());
-             rd->SetProngIDs(3,id);
-             v->SetParent(rd);
-           } else {
-             new(aodD0toKpiRef[i3Prong++]) AliAODRecoDecayHF3Prong(*io3Prong);
-           }
+           AliAODVertex *v3Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
+           if(fInputAOD) AddDaughterRefs(v3Prong,event,threeTrackArray);
+           rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
+           rd->SetSecondaryVtx(v3Prong);
+           v3Prong->SetParent(rd);
          }
-         if(io3Prong) { /*delete io3Prong;*/ io3Prong=NULL; } 
+         if(io3Prong) io3Prong=NULL; 
        }
        negtrack2 = 0;
        delete vertexp1n2;
@@ -466,319 +527,142 @@ void AliAnalysisVertexingHF::FindCandidatesESDtoAOD(AliESDEvent *esd,
   }  // end 1st loop on positive tracks
 
 
+  AliDebug(1,Form(" Total HF vertices in event = %d;",
+                 (Int_t)aodVerticesHFTClArr->GetEntriesFast()));
   if(fD0toKpi) {
-    printf(" D0->Kpi in event %d = %d;\n",
-          (Int_t)esd->GetEventNumberInFile(),
-          (Int_t)aodD0toKpiTClArr->GetEntriesFast());
+    AliDebug(1,Form(" D0->Kpi in event = %d;",
+                   (Int_t)aodD0toKpiTClArr->GetEntriesFast()));
   }
   if(fJPSItoEle) {
-    printf(" JPSI->ee in event %d = %d;\n",
-          (Int_t)esd->GetEventNumberInFile(),
-          (Int_t)aodJPSItoEleTClArr->GetEntriesFast());
+    AliDebug(1,Form(" JPSI->ee in event = %d;",
+                   (Int_t)aodJPSItoEleTClArr->GetEntriesFast()));
   }
   if(f3Prong) {
-    printf(" Charm->3Prong in event %d = %d;\n",
-          (Int_t)esd->GetEventNumberInFile(),
-          (Int_t)aodCharm3ProngTClArr->GetEntriesFast());
+    AliDebug(1,Form(" Charm->3Prong in event = %d;",
+                   (Int_t)aodCharm3ProngTClArr->GetEntriesFast()));
   }
   if(f4Prong) {
-    printf(" Charm->4Prong in event %d = %d;\n",
-          (Int_t)esd->GetEventNumberInFile(),
-          (Int_t)aodCharm4ProngTClArr->GetEntriesFast());
+    AliDebug(1,Form(" Charm->4Prong in event = %d;\n",
+                   (Int_t)aodCharm4ProngTClArr->GetEntriesFast()));
+  }
+  if(fDstar) {
+    AliDebug(1,Form(" D*->D0pi in event = %d;\n",
+                   (Int_t)aodDstarTClArr->GetEntriesFast()));
   }
     
 
-  //printf("delete twoTr 1\n");
-  twoTrackArray1->Delete(); delete twoTrackArray1;
-  //printf("delete twoTr 2\n");
-  twoTrackArray2->Delete(); delete twoTrackArray2;
-  //printf("delete threeTr 1\n");
+  twoTrackArray1->Delete();  delete twoTrackArray1;
+  twoTrackArray2->Delete();  delete twoTrackArray2;
+  twoTrackArrayCasc->Delete();  delete twoTrackArrayCasc;
   threeTrackArray->Clear(); 
   threeTrackArray->Delete(); delete threeTrackArray;
-  //printf("delete fourTr 1\n");
-  fourTrackArray->Delete(); delete fourTrackArray;
+  fourTrackArray->Delete();  delete fourTrackArray;
+  delete [] seleFlags; seleFlags=NULL;
 
-  //------- END SINGLE EVENT ANALYSIS --------------------------------
+  if(fInputAOD) {
+    seleTrksArray.Delete();
+  }
 
   return;
 }
 //----------------------------------------------------------------------------
-void AliAnalysisVertexingHF::FindCandidates(AliESDEvent *esd,TTree *treeout[])
+void AliAnalysisVertexingHF::AddDaughterRefs(AliAODVertex *v,AliVEvent *event,
+                                            TObjArray *trkArray) const
 {
-  // Find heavy-flavour vertex candidates
-  //
-  // DEPRECATED: use FindCandidatesESDtoAOD!
-  
-  fUseTRef=kFALSE; // cannot use TRefs outside AOD
-
-  AliAODRecoDecayHF2Prong *io2Prong = new AliAODRecoDecayHF2Prong();
-  AliAODRecoDecayHF3Prong *io3Prong = new AliAODRecoDecayHF3Prong();
-  AliAODRecoDecayHF4Prong *io4Prong = new AliAODRecoDecayHF4Prong();
-  Int_t itree=0;
-  Int_t itreeD0toKpi=-1,itreeJPSItoEle=-1,itree3Prong=-1,itree4Prong=-1;
-  Int_t initEntriesD0toKpi=0,initEntriesJPSItoEle=0,initEntries3Prong=0,initEntries4Prong=0;
-  if(fD0toKpi) {
-    itreeD0toKpi=itree;
-    treeout[itree]->SetBranchAddress("D0toKpi",&io2Prong);
-    itree++;
-    initEntriesD0toKpi = treeout[itreeD0toKpi]->GetEntries();
-  }
-  if(fJPSItoEle) {
-    itreeJPSItoEle=itree;
-    treeout[itree]->SetBranchAddress("JPSItoEle",&io2Prong);
-    itree++;
-    initEntriesJPSItoEle = treeout[itreeJPSItoEle]->GetEntries();
-  }
-  if(f3Prong) {
-    itree3Prong=itree;
-    treeout[itree]->SetBranchAddress("Charmto3Prong",&io3Prong);
-    itree++;
-    initEntries3Prong = treeout[itree3Prong]->GetEntries();
-  }
-  if(f4Prong) {
-    itree4Prong=itree;
-    treeout[itree]->SetBranchAddress("D0to4Prong",&io4Prong);
-    itree++;
-    initEntries4Prong = treeout[itree4Prong]->GetEntries();
-  }
-  delete io2Prong; io2Prong = NULL;
-  delete io3Prong; io3Prong = NULL;
-  delete io4Prong; io4Prong = NULL;
-
-  Int_t    iTrkP1,iTrkP2,iTrkN1,iTrkN2,trkEntries;
-  Int_t    nTrksP=0,nTrksN=0;
-  Double_t xdummy,ydummy,dcap1n1,dcap1n2,dcap2n1,dcap1p2,dcan1n2;
-  Bool_t   okD0=kFALSE,okJPSI=kFALSE,ok3Prong=kFALSE,ok4Prong=kFALSE;
-  AliESDtrack *postrack1 = 0;
-  AliESDtrack *postrack2 = 0;
-  AliESDtrack *negtrack1 = 0;
-  AliESDtrack *negtrack2 = 0;
-  Double_t dcaMax = fD0toKpiCuts[1];
-  if(dcaMax<fBtoJPSICuts[1]) dcaMax=fBtoJPSICuts[1];
-  if(dcaMax<fDplusCuts[11]) dcaMax=fDplusCuts[11];
-  if(fDebug) printf(" dca cut set to %f cm\n",dcaMax);
-
-  Int_t ev = (Int_t)esd->GetEventNumberInFile();
-  printf("--- Finding candidates in event %d\n",ev);
+  // Add the AOD tracks as daughters of the vertex (TRef)
 
-  fBzkG = (Double_t)esd->GetMagneticField(); 
+  Int_t nTrks = trkArray->GetEntriesFast();
 
-  trkEntries = (Int_t)esd->GetNumberOfTracks();
-  printf(" Number of tracks: %d\n",trkEntries);
-  if(trkEntries<2) return;
+  AliExternalTrackParam *track = 0;
+  AliAODTrack *aodTrack = 0;
+  Int_t id;
 
-  // retrieve primary vertex from the AliESDEvent
-  if(!esd->GetPrimaryVertex()) { 
-    printf(" No vertex in AliESD\n");
-    return;
+  for(Int_t i=0; i<nTrks; i++) {
+    track = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
+    id = (Int_t)track->GetID();
+    //printf("---> %d\n",id);
+    if(id<0) continue; // this track is a AliAODRecoDecay
+    aodTrack = (AliAODTrack*)event->GetTrack(fAODMap[id]);
+    v->AddDaughter(aodTrack);
   }
-  AliESDVertex copy(*(esd->GetPrimaryVertex()));
-  SetPrimaryVertex(&copy);
-
-  // call function which applies sigle-track selection and
-  // separetes positives and negatives
-  TObjArray trksP(trkEntries/2); 
-  TObjArray trksN(trkEntries/2); 
-  SelectTracks(esd,trksP,nTrksP,
-                  trksN,nTrksN);
-
-  printf(" Pos. tracks: %d    Neg. tracks: %d\n",nTrksP,nTrksN);
-
-  TObjArray *twoTrackArray1 = new TObjArray(2);
-  TObjArray *twoTrackArray2 = new TObjArray(2);
-  TObjArray *threeTrackArray = new TObjArray(3);
-  TObjArray *fourTrackArray = new TObjArray(4);
-
-  // LOOP ON  POSITIVE  TRACKS
-  for(iTrkP1=0; iTrkP1<nTrksP; iTrkP1++) {
-    if(fDebug) if(iTrkP1%1==0) printf("  Processing positive track number %d of %d\n",iTrkP1,nTrksP);  
-    // get track from track array
-    postrack1 = (AliESDtrack*)trksP.UncheckedAt(iTrkP1);
-
-    // LOOP ON  NEGATIVE  TRACKS
-    for(iTrkN1=0; iTrkN1<nTrksN; iTrkN1++) {
-      if(fDebug) if(iTrkN1%1==0) printf("    Processing negative track number %d of %d\n",iTrkN1,nTrksN);  
-      // get track from tracks array
-      negtrack1 = (AliESDtrack*)trksN.UncheckedAt(iTrkN1);
-      // DCA between the two tracks
-      dcap1n1 = postrack1->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
-      if(dcap1n1>dcaMax) { negtrack1=0; continue; }
-      // Vertexing
-      twoTrackArray1->AddAt(postrack1,0);
-      twoTrackArray1->AddAt(negtrack1,1);
-      AliESDVertex *vertexp1n1 = ReconstructSecondaryVertex(twoTrackArray1);
-      if(!vertexp1n1) { 
-       twoTrackArray1->Clear();
-       negtrack1=0; 
-       continue; 
-      }
-      if(fD0toKpi || fJPSItoEle) { 
-       io2Prong = Make2Prong(twoTrackArray1,esd,vertexp1n1,dcap1n1,okD0,okJPSI);
-       if(okD0)   treeout[itreeD0toKpi]->Fill();
-       if(okJPSI) treeout[itreeJPSItoEle]->Fill();
-        delete io2Prong; io2Prong=NULL; 
-      }
 
-      twoTrackArray1->Clear(); 
-      if(!f3Prong && !f4Prong)  { 
-       negtrack1=0; 
-       delete vertexp1n1; 
-       continue; 
-      }
-      
-      // 2nd LOOP  ON  POSITIVE  TRACKS 
-      for(iTrkP2=iTrkP1+1; iTrkP2<nTrksP; iTrkP2++) {
-       // get track from tracks array
-       postrack2 = (AliESDtrack*)trksP.UncheckedAt(iTrkP2);
-       dcap2n1 = postrack2->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
-       if(dcap2n1>dcaMax) { postrack2=0; continue; }
-       dcap1p2 = postrack2->GetDCA(postrack1,fBzkG,xdummy,ydummy);
-       if(dcap1p2>dcaMax) { postrack2=0; continue; }
-
-       // Vertexing
-       twoTrackArray2->AddAt(postrack2,0);
-       twoTrackArray2->AddAt(negtrack1,1);
-       AliESDVertex *vertexp2n1 = ReconstructSecondaryVertex(twoTrackArray2);
-       if(!vertexp2n1) { 
-         twoTrackArray2->Clear();
-         postrack2=0; 
-         continue; 
-       }
-       if(f3Prong) { 
-         threeTrackArray->AddAt(postrack1,0);
-         threeTrackArray->AddAt(negtrack1,1);
-         threeTrackArray->AddAt(postrack2,2);
-         io3Prong = Make3Prong(threeTrackArray,esd,vertexp1n1,vertexp2n1,dcap1n1,dcap2n1,dcap1p2,ok3Prong);
-         if(ok3Prong) treeout[itree3Prong]->Fill();
-         if(io3Prong) delete io3Prong; io3Prong=NULL; 
-       }
-       if(f4Prong) {
-         // 3rd LOOP  ON  NEGATIVE  TRACKS (for 4 prong) 
-         for(iTrkN2=iTrkN1+1; iTrkN2<nTrksN; iTrkN2++) {
-           // get track from tracks array
-           negtrack2 = (AliESDtrack*)trksN.UncheckedAt(iTrkN2);
-           dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
-           if(dcap1n2>dcaMax) { negtrack2=0; continue; }
-           // Vertexing
-           fourTrackArray->AddAt(postrack1,0);
-           fourTrackArray->AddAt(negtrack1,1);
-           fourTrackArray->AddAt(postrack2,2);
-           fourTrackArray->AddAt(negtrack2,3);
-           io4Prong = Make4Prong(fourTrackArray,esd,vertexp1n1,vertexp2n1,dcap1n1,dcap1n2,dcap2n1,ok4Prong);
-           if(ok4Prong) treeout[itree4Prong]->Fill();
-           delete io4Prong; io4Prong=NULL; 
-            fourTrackArray->Clear();
-           negtrack2 = 0;
-         } // end loop on negative tracks
-       }
-       postrack2 = 0;
-       delete vertexp2n1;
-      } // end 2nd loop on positive tracks
-      twoTrackArray2->Clear();
-      
-      // 2nd LOOP  ON  NEGATIVE  TRACKS 
-      for(iTrkN2=iTrkN1+1; iTrkN2<nTrksN; iTrkN2++) {
-       // get track from tracks array
-       negtrack2 = (AliESDtrack*)trksN.UncheckedAt(iTrkN2);
-       dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
-       if(dcap1n2>dcaMax) { negtrack2=0; continue; }
-       dcan1n2 = negtrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
-       if(dcan1n2>dcaMax) { negtrack2=0; continue; }
-
-       // Vertexing
-       twoTrackArray2->AddAt(postrack1,0);
-       twoTrackArray2->AddAt(negtrack2,1);
-       AliESDVertex *vertexp1n2 = ReconstructSecondaryVertex(twoTrackArray2);
-       if(!vertexp1n2) { 
-         twoTrackArray2->Clear();
-         negtrack2=0; 
-         continue; 
-       }
-       if(f3Prong) { 
-         threeTrackArray->AddAt(negtrack1,0);
-         threeTrackArray->AddAt(postrack1,1);
-         threeTrackArray->AddAt(negtrack2,2);
-         io3Prong = Make3Prong(threeTrackArray,esd,vertexp1n1,vertexp1n2,dcap1n1,dcap1n2,dcan1n2,ok3Prong);
-         if(ok3Prong) treeout[itree3Prong]->Fill();
-         if(io3Prong) delete io3Prong; io3Prong=NULL; 
-         }
-       negtrack2 = 0;
-       delete vertexp1n2;
-      } // end 2nd loop on negative tracks
-      twoTrackArray2->Clear();
-
-      negtrack1 = 0;
-      delete vertexp1n1; 
-    } // end 1st loop on negative tracks
+  return;
+}      
+//----------------------------------------------------------------------------
+AliAODRecoCascadeHF* AliAnalysisVertexingHF::MakeCascade(
+                                  TObjArray *twoTrackArray,AliVEvent *event,
+                                  AliAODVertex *secVert,
+                                  AliAODRecoDecayHF2Prong *rd2Prong,
+                                  Double_t dca,
+                                  Bool_t &okDstar) const
+{
+  // Make the cascade as a 2Prong decay and check if it passes Dstar
+  // reconstruction cuts
 
-    postrack1 = 0;
-  }  // end 1st loop on positive tracks
-    
+  okDstar = kFALSE;
 
+  Bool_t dummy1,dummy2,dummy3;
 
-  //printf("delete twoTr 1\n");
-  twoTrackArray1->Delete(); delete twoTrackArray1;
-  //printf("delete twoTr 2\n");
-  twoTrackArray2->Delete(); delete twoTrackArray2;
-  //printf("delete threeTr 1\n");
-  threeTrackArray->Clear(); 
-  threeTrackArray->Delete(); delete threeTrackArray;
-  //printf("delete fourTr 1\n");
-  fourTrackArray->Delete(); delete fourTrackArray;
+  // We use Make2Prong to construct the AliAODRecoCascadeHF
+  // (which inherits from AliAODRecoDecayHF2Prong) 
+  AliAODRecoCascadeHF *theCascade = 
+    (AliAODRecoCascadeHF*)Make2Prong(twoTrackArray,event,secVert,dca,
+                                    dummy1,dummy2,dummy3);
+  if(!theCascade) return 0x0;
 
+  // charge
+  AliESDtrack *trackPi = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
+  theCascade->SetCharge(trackPi->Charge());
 
-  // create a copy of this class to be written to output file
-  //AliAnalysisVertexingHF *copy = (AliAnalysisVertexingHF*)this->Clone("AnalysisVertexingHF");
-
-  // print statistics
-  if(fD0toKpi) {
-    printf(" D0->Kpi: event %d = %d; total = %d;\n",
-          (Int_t)esd->GetEventNumberInFile(),
-          (Int_t)treeout[itreeD0toKpi]->GetEntries()-initEntriesD0toKpi,
-          (Int_t)treeout[itreeD0toKpi]->GetEntries());
+  //--- selection cuts
+  //
+  AliAODRecoCascadeHF *tmpCascade = new AliAODRecoCascadeHF(*theCascade);
+  tmpCascade->GetSecondaryVtx()->AddDaughter(trackPi);
+  tmpCascade->GetSecondaryVtx()->AddDaughter(rd2Prong);
+  AliAODVertex *primVertexAOD=0;
+  if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
+    // take event primary vertex
+    primVertexAOD = PrimaryVertex(); 
+    tmpCascade->SetOwnPrimaryVtx(primVertexAOD);
+    rd2Prong->SetOwnPrimaryVtx(primVertexAOD);
   }
-  if(fJPSItoEle) {
-    printf(" JPSI->ee: event %d = %d; total = %d;\n",
-          (Int_t)esd->GetEventNumberInFile(),
-          (Int_t)treeout[itreeJPSItoEle]->GetEntries()-initEntriesJPSItoEle,
-          (Int_t)treeout[itreeJPSItoEle]->GetEntries());
+  // select D*->D0pi
+  if(fDstar) {
+    Bool_t testD0=kTRUE;
+    okDstar = tmpCascade->SelectDstar(fDstarCuts,fD0fromDstarCuts,testD0);
   }
-  if(f3Prong) {
-    printf(" Charm->3Prong: event %d = %d; total = %d;\n",
-   (Int_t)esd->GetEventNumberInFile(),
-          (Int_t)treeout[itree3Prong]->GetEntries()-initEntries3Prong,
-          (Int_t)treeout[itree3Prong]->GetEntries());
+  tmpCascade->GetSecondaryVtx()->RemoveDaughters();
+  tmpCascade->UnsetOwnPrimaryVtx(); 
+  delete tmpCascade; tmpCascade=NULL;
+  if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
+    rd2Prong->UnsetOwnPrimaryVtx();
+    delete primVertexAOD; primVertexAOD=NULL;
   }
-  if(f4Prong) {
-    printf(" Charm->4Prong: event %d = %d; total = %d;\n",
-          (Int_t)esd->GetEventNumberInFile(),
-          (Int_t)treeout[itree4Prong]->GetEntries()-initEntries4Prong,
-          (Int_t)treeout[itree4Prong]->GetEntries());
-  }
-
-
-  return;
+  //---
+  
+  return theCascade;
 }
-//----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 AliAODRecoDecayHF2Prong *AliAnalysisVertexingHF::Make2Prong(
-                                  TObjArray *twoTrackArray1,AliESDEvent *esd,
-                                  AliESDVertex *secVertexESD,Double_t dca,
-                                  Bool_t &okD0,Bool_t &okJPSI) const
+                                  TObjArray *twoTrackArray,AliVEvent *event,
+                                  AliAODVertex *secVert,Double_t dca,
+                                  Bool_t &okD0,Bool_t &okJPSI,
+                                  Bool_t &okD0fromDstar) const
 {
   // Make 2Prong candidates and check if they pass D0toKpi or BtoJPSI
   // reconstruction cuts
   // G.E.Bruno (J/psi), A.Dainese (D0->Kpi)
 
-  okD0=kFALSE; okJPSI=kFALSE;
+  okD0=kFALSE; okJPSI=kFALSE; okD0fromDstar=kFALSE;
 
   Double_t px[2],py[2],pz[2],d0[2],d0err[2];
 
-  AliESDtrack *postrack = (AliESDtrack*)twoTrackArray1->UncheckedAt(0);
-  AliESDtrack *negtrack = (AliESDtrack*)twoTrackArray1->UncheckedAt(1);
+  AliESDtrack *postrack = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
+  AliESDtrack *negtrack = (AliESDtrack*)twoTrackArray->UncheckedAt(1);
 
   // propagate tracks to secondary vertex, to compute inv. mass
-  postrack->RelateToVertex(secVertexESD,fBzkG,10.);
-  negtrack->RelateToVertex(secVertexESD,fBzkG,10.);
+  postrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
+  negtrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
 
   Double_t momentum[3];
   postrack->GetPxPyPz(momentum);
@@ -789,87 +673,67 @@ AliAODRecoDecayHF2Prong *AliAnalysisVertexingHF::Make2Prong(
 
   // invariant mass cut (try to improve coding here..)
   Bool_t okMassCut=kFALSE;
-  if(!okMassCut && fD0toKpi) if(SelectInvMass(0,2,px,py,pz)) okMassCut=kTRUE;
+  if(!okMassCut && fD0toKpi)   if(SelectInvMass(0,2,px,py,pz)) okMassCut=kTRUE;
   if(!okMassCut && fJPSItoEle) if(SelectInvMass(1,2,px,py,pz)) okMassCut=kTRUE;
+  if(!okMassCut && fDstar)     if(SelectInvMass(3,2,px,py,pz)) okMassCut=kTRUE;
   if(!okMassCut) {
-    if(fDebug) printf(" candidate didn't pass mass cut\n");
+    AliDebug(2," candidate didn't pass mass cut");
     return 0x0;    
   }
 
+  // primary vertex to be used by this candidate
+  AliAODVertex *primVertexAOD  = PrimaryVertex(twoTrackArray,event);
+  if(!primVertexAOD) return 0x0;
 
-  AliESDVertex *primVertex = fV1;  
-  AliESDVertex *ownPrimVertex=0;
-
-  // primary vertex from *other* tracks in the event
-  if(fRecoPrimVtxSkippingTrks || fRmTrksFromPrimVtx) {
-    ownPrimVertex = OwnPrimaryVertex(2,twoTrackArray1,esd);
-    if(!ownPrimVertex) {
-      return 0x0;
-    } else {
-      if(ownPrimVertex->GetNContributors()<2) {
-       delete ownPrimVertex;
-       return 0x0;
-      } else {
-       primVertex = ownPrimVertex;
-      }
-    }
-  }
-
-  Float_t d0z0[2],covd0z0[3];
-  postrack->RelateToVertex(primVertex,fBzkG,10.);
-  postrack->GetImpactParameters(d0z0,covd0z0);
+  Double_t d0z0[2],covd0z0[3];
+  postrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
   d0[0] = d0z0[0];
   d0err[0] = TMath::Sqrt(covd0z0[0]);
-  negtrack->RelateToVertex(primVertex,fBzkG,10.);
-  negtrack->GetImpactParameters(d0z0,covd0z0);
+  negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
   d0[1] = d0z0[0];
   d0err[1] = TMath::Sqrt(covd0z0[0]);
 
   // create the object AliAODRecoDecayHF2Prong
-  Double_t pos[3],cov[6];
-  secVertexESD->GetXYZ(pos); // position
-  secVertexESD->GetCovMatrix(cov); //covariance matrix
-  AliAODVertex *secVertexAOD = new AliAODVertex(pos,cov,secVertexESD->GetChi2toNDF());
-  AliAODRecoDecayHF2Prong *the2Prong = new AliAODRecoDecayHF2Prong(secVertexAOD,px,py,pz,d0,d0err,dca);
-  the2Prong->SetOwnSecondaryVtx(secVertexAOD);
-  primVertex->GetXYZ(pos); // position
-  primVertex->GetCovMatrix(cov); //covariance matrix
-  AliAODVertex *primVertexAOD = new AliAODVertex(pos,cov,primVertex->GetChi2toNDF());
+  AliAODRecoDecayHF2Prong *the2Prong = new AliAODRecoDecayHF2Prong(secVert,px,py,pz,d0,d0err,dca);
   the2Prong->SetOwnPrimaryVtx(primVertexAOD);
+  UShort_t id[2]={(UShort_t)postrack->GetID(),(UShort_t)negtrack->GetID()};
+  the2Prong->SetProngIDs(2,id);
 
 
   // select D0->Kpi
   Int_t checkD0,checkD0bar;
-  if(fD0toKpi) okD0 = the2Prong->SelectD0(fD0toKpiCuts,checkD0,checkD0bar);
+  if(fD0toKpi)   okD0          = the2Prong->SelectD0(fD0toKpiCuts,checkD0,checkD0bar);
   //if(fDebug && fD0toKpi) printf("   %d\n",(Int_t)okD0);
   // select J/psi from B
   Int_t checkJPSI;
-  if(fJPSItoEle) okJPSI = the2Prong->SelectBtoJPSI(fBtoJPSICuts,checkJPSI);
+  if(fJPSItoEle) okJPSI        = the2Prong->SelectBtoJPSI(fBtoJPSICuts,checkJPSI);
   //if(fDebug && fJPSItoEle) printf("   %d\n",(Int_t)okJPSI);
+  // select D0->Kpi from Dstar
+  if(fDstar)     okD0fromDstar = the2Prong->SelectD0(fD0fromDstarCuts,checkD0,checkD0bar);
+  //if(fDebug && fDstar) printf("   %d\n",(Int_t)okD0fromDstar);
 
+  // remove the primary vertex (was used only for selection)
+  if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) the2Prong->UnsetOwnPrimaryVtx();
 
-  if(okD0 || okJPSI) {
-    // get PID info from ESD
-    Double_t esdpid0[5];
-    postrack->GetESDpid(esdpid0);
-    Double_t esdpid1[5];
-    negtrack->GetESDpid(esdpid1);
-    Double_t esdpid[10];
-    for(Int_t i=0;i<5;i++) {
-      esdpid[i]   = esdpid0[i];
-      esdpid[5+i] = esdpid1[i];
-    }
-    the2Prong->SetPID(2,esdpid);
+  // get PID info from ESD
+  Double_t esdpid0[5];
+  postrack->GetESDpid(esdpid0);
+  Double_t esdpid1[5];
+  negtrack->GetESDpid(esdpid1);
+  Double_t esdpid[10];
+  for(Int_t i=0;i<5;i++) {
+    esdpid[i]   = esdpid0[i];
+    esdpid[5+i] = esdpid1[i];
   }
+  the2Prong->SetPID(2,esdpid);
 
-  if(ownPrimVertex) delete ownPrimVertex;      
   return the2Prong;  
 }
 //----------------------------------------------------------------------------
 AliAODRecoDecayHF3Prong* AliAnalysisVertexingHF::Make3Prong(
-                             TObjArray *threeTrackArray,AliESDEvent *esd,
-                            AliESDVertex *vertexp1n1,AliESDVertex *vertexp2n1,
+                             TObjArray *threeTrackArray,AliVEvent *event,
+                            AliAODVertex *secVert,Double_t dispersion,
+                            AliAODVertex *vertexp1n1,AliAODVertex *vertexp2n1,
                             Double_t dcap1n1,Double_t dcap2n1,Double_t dcap1p2,
                             Bool_t &ok3Prong) const
 {
@@ -877,22 +741,21 @@ AliAODRecoDecayHF3Prong* AliAnalysisVertexingHF::Make3Prong(
   // reconstruction cuts 
   // E.Bruna, F.Prino
 
+
   ok3Prong=kFALSE;
-  Double_t px[3],py[3],pz[3],d0[3],d0err[3];//d0z[3];  
-  Float_t d0z0[2],covd0z0[3];
+  if(!secVert) return 0x0; 
+
+  Double_t px[3],py[3],pz[3],d0[3],d0err[3];
+  Double_t momentum[3];
 
 
   AliESDtrack *postrack1 = (AliESDtrack*)threeTrackArray->UncheckedAt(0);
-  AliESDtrack *negtrack = (AliESDtrack*)threeTrackArray->UncheckedAt(1);
+  AliESDtrack *negtrack  = (AliESDtrack*)threeTrackArray->UncheckedAt(1);
   AliESDtrack *postrack2 = (AliESDtrack*)threeTrackArray->UncheckedAt(2);
 
-  AliESDVertex *primVertex = fV1;  
-
-  postrack1->RelateToVertex(primVertex,fBzkG,10.);
-  negtrack->RelateToVertex(primVertex,fBzkG,10.);
-  postrack2->RelateToVertex(primVertex,fBzkG,10.);
-
-  Double_t momentum[3];
+  postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
+  negtrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
+  postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
   postrack1->GetPxPyPz(momentum);
   px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2]; 
   negtrack->GetPxPyPz(momentum);
@@ -900,67 +763,40 @@ AliAODRecoDecayHF3Prong* AliAnalysisVertexingHF::Make3Prong(
   postrack2->GetPxPyPz(momentum);
   px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2]; 
 
-  postrack1->GetImpactParameters(d0z0,covd0z0);
-  d0[0]=d0z0[0];
-  d0err[0] = TMath::Sqrt(covd0z0[0]);
-  negtrack->GetImpactParameters(d0z0,covd0z0);
-  d0[1]=d0z0[0];
-  d0err[1] = TMath::Sqrt(covd0z0[0]);
-  postrack2->GetImpactParameters(d0z0,covd0z0);
-  d0[2]=d0z0[0];
-  d0err[2] = TMath::Sqrt(covd0z0[0]);
-
-
   // invariant mass cut for D+, Ds, Lc
   Bool_t okMassCut=kFALSE;
   if(!okMassCut && f3Prong) if(SelectInvMass(2,3,px,py,pz)) okMassCut=kTRUE;
   if(!okMassCut) {
-    if(fDebug) printf(" candidate didn't pass mass cut\n");
+    AliDebug(2," candidate didn't pass mass cut");
     return 0x0;    
   }
 
-  //charge
-  Short_t charge=(Short_t)(postrack1->GetSign()*postrack2->GetSign()*negtrack->GetSign());
+  // primary vertex to be used by this candidate
+  AliAODVertex *primVertexAOD  = PrimaryVertex(threeTrackArray,event);
+  if(!primVertexAOD) return 0x0;
+
+  Double_t d0z0[2],covd0z0[3];
+  postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
+  d0[0]=d0z0[0];
+  d0err[0] = TMath::Sqrt(covd0z0[0]);
+  negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
+  d0[1]=d0z0[0];
+  d0err[1] = TMath::Sqrt(covd0z0[0]);
+  postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
+  d0[2]=d0z0[0];
+  d0err[2] = TMath::Sqrt(covd0z0[0]);
 
-  AliESDVertex *ownPrimVertex = 0;  
-  // primary vertex from *other* tracks in the event
-  if(fRecoPrimVtxSkippingTrks || fRmTrksFromPrimVtx) {
-    ownPrimVertex = OwnPrimaryVertex(3,threeTrackArray,esd);
-    if(!ownPrimVertex) {
-      return 0x0;
-    } else {
-      if(ownPrimVertex->GetNContributors()<2) {
-       delete ownPrimVertex;
-       return 0x0;
-      } else {
-       primVertex = ownPrimVertex;
-      }
-    }
-  }
 
   // create the object AliAODRecoDecayHF3Prong
-  AliESDVertex* secVert3Prong = ReconstructSecondaryVertex(threeTrackArray);
-  if(!secVert3Prong) { 
-    if(ownPrimVertex) delete ownPrimVertex;    
-    return 0x0; 
-  }
-  Double_t pos[3],cov[6],sigmavert;
-  secVert3Prong->GetXYZ(pos); // position
-  secVert3Prong->GetCovMatrix(cov); //covariance matrix
-  sigmavert=secVert3Prong->GetDispersion();
-
-  AliAODVertex *secVert3PrAOD = new AliAODVertex(pos,cov,secVert3Prong->GetChi2toNDF());
-  primVertex->GetXYZ(pos); // position
-  primVertex->GetCovMatrix(cov); //covariance matrix
-  AliAODVertex *primVertexAOD = new AliAODVertex(pos,cov,primVertex->GetChi2toNDF());
+  Double_t pos[3]; primVertexAOD->GetXYZ(pos);
   Double_t dca[3]={dcap1n1,dcap2n1,dcap1p2};
-
-  Double_t dist12=TMath::Sqrt((vertexp1n1->GetXv()-pos[0])*(vertexp1n1->GetXv()-pos[0])+(vertexp1n1->GetYv()-pos[1])*(vertexp1n1->GetYv()-pos[1])+(vertexp1n1->GetZv()-pos[2])*(vertexp1n1->GetZv()-pos[2]));
-  Double_t dist23=TMath::Sqrt((vertexp2n1->GetXv()-pos[0])*(vertexp2n1->GetXv()-pos[0])+(vertexp2n1->GetYv()-pos[1])*(vertexp2n1->GetYv()-pos[1])+(vertexp2n1->GetZv()-pos[2])*(vertexp2n1->GetZv()-pos[2]));
-
-  AliAODRecoDecayHF3Prong *the3Prong = new AliAODRecoDecayHF3Prong(secVert3PrAOD,px,py,pz,d0,d0err,dca,sigmavert,dist12,dist23,charge);
-  the3Prong->SetOwnSecondaryVtx(secVert3PrAOD);
+  Double_t dist12=TMath::Sqrt((vertexp1n1->GetX()-pos[0])*(vertexp1n1->GetX()-pos[0])+(vertexp1n1->GetY()-pos[1])*(vertexp1n1->GetY()-pos[1])+(vertexp1n1->GetZ()-pos[2])*(vertexp1n1->GetZ()-pos[2]));
+  Double_t dist23=TMath::Sqrt((vertexp2n1->GetX()-pos[0])*(vertexp2n1->GetX()-pos[0])+(vertexp2n1->GetY()-pos[1])*(vertexp2n1->GetY()-pos[1])+(vertexp2n1->GetZ()-pos[2])*(vertexp2n1->GetZ()-pos[2]));
+  Short_t charge=(Short_t)(postrack1->Charge()*postrack2->Charge()*negtrack->Charge());
+  AliAODRecoDecayHF3Prong *the3Prong = new AliAODRecoDecayHF3Prong(secVert,px,py,pz,d0,d0err,dca,dispersion,dist12,dist23,charge);
   the3Prong->SetOwnPrimaryVtx(primVertexAOD);
+  UShort_t id[3]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack->GetID(),(UShort_t)postrack2->GetID()};
+  the3Prong->SetProngIDs(3,id);
 
 
   // select D+->Kpipi, Ds->KKpi, Lc->pKpi
@@ -972,33 +808,32 @@ AliAODRecoDecayHF3Prong* AliAnalysisVertexingHF::Make3Prong(
     if(the3Prong->SelectLc(fLcCuts,ok1,ok2)) ok3Prong = kTRUE;
   }
   //if(fDebug) printf("ok3Prong: %d\n",(Int_t)ok3Prong);
-  if(ok3Prong) {
-    // get PID info from ESD
-    Double_t esdpid0[5];
-    postrack1->GetESDpid(esdpid0);
-    Double_t esdpid1[5];
-    negtrack->GetESDpid(esdpid1);
-    Double_t esdpid2[5];
-    postrack2->GetESDpid(esdpid2);
-
-
-    Double_t esdpid[15];
-    for(Int_t i=0;i<5;i++) {
-      esdpid[i]   = esdpid0[i];
-      esdpid[5+i] = esdpid1[i];
-      esdpid[10+i] = esdpid2[i];
-    }
-    the3Prong->SetPID(3,esdpid);
-  }
 
-  if(ownPrimVertex) delete ownPrimVertex;      
+  if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) the3Prong->UnsetOwnPrimaryVtx();
+
+  // get PID info from ESD
+  Double_t esdpid0[5];
+  postrack1->GetESDpid(esdpid0);
+  Double_t esdpid1[5];
+  negtrack->GetESDpid(esdpid1);
+  Double_t esdpid2[5];
+  postrack2->GetESDpid(esdpid2);
+  
+  Double_t esdpid[15];
+  for(Int_t i=0;i<5;i++) {
+    esdpid[i]    = esdpid0[i];
+    esdpid[5+i]  = esdpid1[i];
+    esdpid[10+i] = esdpid2[i];
+  }
+  the3Prong->SetPID(3,esdpid);
 
   return the3Prong;
 }
 //----------------------------------------------------------------------------
 AliAODRecoDecayHF4Prong* AliAnalysisVertexingHF::Make4Prong(
-                             TObjArray *fourTrackArray,AliESDEvent *esd,
-                            AliESDVertex *vertexp1n1,AliESDVertex *vertexp2n1,
+                             TObjArray *fourTrackArray,AliVEvent *event,
+                            AliAODVertex *secVert,
+                            AliAODVertex *vertexp1n1,AliAODVertex *vertexp2n1,
                             Double_t dcap1n1,Double_t dcap1n2,Double_t dcap2n1,
                             Bool_t &ok4Prong) const
 {
@@ -1007,26 +842,21 @@ AliAODRecoDecayHF4Prong* AliAnalysisVertexingHF::Make4Prong(
   // G.E.Bruno, R.Romita
 
   ok4Prong=kFALSE;
+  if(!secVert) return 0x0; 
 
   Double_t px[4],py[4],pz[4],d0[4],d0err[4];//d0z[3];
-  //Float_t d0z0[2],covd0z0[3];
 
   px[0]=dcap1n1*dcap1n2*dcap2n1; // TO BE CHANGED (done just to removed compilation warning about dca... not used)
 
-  //charge
-  Short_t charge=0;
-
   AliESDtrack *postrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(0);
   AliESDtrack *negtrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(1);
   AliESDtrack *postrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(2);
   AliESDtrack *negtrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(3);
 
-  AliESDVertex *primVertex = fV1;
-
-  postrack1->RelateToVertex(primVertex,fBzkG,10.);
-  negtrack1->RelateToVertex(primVertex,fBzkG,10.);
-  postrack2->RelateToVertex(primVertex,fBzkG,10.);
-  negtrack2->RelateToVertex(primVertex,fBzkG,10.);
+  postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
+  negtrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
+  postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
+  negtrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
 
   Double_t momentum[3];
   postrack1->GetPxPyPz(momentum);
@@ -1046,49 +876,30 @@ AliAODRecoDecayHF4Prong* AliAnalysisVertexingHF::Make4Prong(
   //  return 0x0;
   //}
 
-  AliESDVertex *ownPrimVertex = 0;
-  // primary vertex from *other* tracks in the event
-  if(fRecoPrimVtxSkippingTrks || fRmTrksFromPrimVtx) {
-    ownPrimVertex = OwnPrimaryVertex(4,fourTrackArray,esd);
-    if(!ownPrimVertex) {
-      return 0x0;
-    } else {
-      if(ownPrimVertex->GetNContributors()<2) {
-        delete ownPrimVertex;
-        return 0x0;
-      } else {
-        primVertex = ownPrimVertex;
-      }
-    }
-  }
+  // primary vertex to be used by this candidate
+  AliAODVertex *primVertexAOD  = PrimaryVertex(fourTrackArray,event);
+  if(!primVertexAOD) return 0x0;
+
+  /*
+    Double_t d0z0[2],covd0z0[3];
+    postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
+    negtrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
+    postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
+    negtrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
+  */
 
   // create the object AliAODRecoDecayHF4Prong
-  AliESDVertex* secVert4Prong = ReconstructSecondaryVertex(fourTrackArray);
-  if(!secVert4Prong) { 
-    if(ownPrimVertex) delete ownPrimVertex;    
-    return 0x0; 
-  }
-  Double_t pos[3],cov[6],sigmavert;
-  secVert4Prong->GetXYZ(pos); // position
-  secVert4Prong->GetCovMatrix(cov); //covariance matrix
-  sigmavert=secVert4Prong->GetDispersion();
-
-  AliAODVertex *secVert4PrAOD = new AliAODVertex(pos,cov,secVert4Prong->GetChi2toNDF());
-  primVertex->GetXYZ(pos); // position
-  primVertex->GetCovMatrix(cov); //covariance matrix
-  AliAODVertex *primVertexAOD = new AliAODVertex(pos,cov,primVertex->GetChi2toNDF());
-  //Double_t dca[6]={dcap1n1,dcap2n1,dcap1p2,0.,0.,0.}; //
+  Double_t pos[3]; primVertexAOD->GetXYZ(pos);
   Double_t dca[6]={0.,0.,0.,0.,0.,0.}; //  modify it
-
-  Double_t dist12=TMath::Sqrt((vertexp1n1->GetXv()-pos[0])*(vertexp1n1->GetXv()-pos[0])+(vertexp1n1->GetYv()-pos[1])*(vertexp1n1->GetYv()-pos[1])+(vertexp1n1->GetZv()-pos[2])*(vertexp1n1->GetZv()-pos[2]));
-  Double_t dist23=TMath::Sqrt((vertexp2n1->GetXv()-pos[0])*(vertexp2n1->GetXv()-pos[0])+(vertexp2n1->GetYv()-pos[1])*(vertexp2n1->GetYv()-pos[1])+(vertexp2n1->GetZv()-pos[2])*(vertexp2n1->GetZv()-pos[2]));
+  Double_t dist12=TMath::Sqrt((vertexp1n1->GetX()-pos[0])*(vertexp1n1->GetX()-pos[0])+(vertexp1n1->GetY()-pos[1])*(vertexp1n1->GetY()-pos[1])+(vertexp1n1->GetZ()-pos[2])*(vertexp1n1->GetZ()-pos[2]));
+  Double_t dist23=TMath::Sqrt((vertexp2n1->GetX()-pos[0])*(vertexp2n1->GetX()-pos[0])+(vertexp2n1->GetY()-pos[1])*(vertexp2n1->GetY()-pos[1])+(vertexp2n1->GetZ()-pos[2])*(vertexp2n1->GetZ()-pos[2]));
   Double_t dist14=0.; // to be implemented
   Double_t dist34=0.; // to be implemented
-
-  //AliAODRecoDecayHF4Prong *the4Prong = new AliAODRecoDecayHF4Prong(secVert4PrAOD,px,py,pz,d0,d0err,dca,sigmavert,dist12,dist23,charge);
-  AliAODRecoDecayHF4Prong *the4Prong = new AliAODRecoDecayHF4Prong(secVert4PrAOD,px,py,pz,d0,d0err,dca,dist12,dist23,dist14,dist34,charge);
+  Short_t charge=0;
+  AliAODRecoDecayHF4Prong *the4Prong = new AliAODRecoDecayHF4Prong(secVert,px,py,pz,d0,d0err,dca,dist12,dist23,dist14,dist34,charge);
   the4Prong->SetOwnPrimaryVtx(primVertexAOD);
-  the4Prong->SetOwnSecondaryVtx(secVert4PrAOD);
+  UShort_t id[4]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack1->GetID(),(UShort_t)postrack2->GetID(),(UShort_t)negtrack2->GetID()};
+  the4Prong->SetProngIDs(4,id);
 
 
   // use the following two lines once AliAODRecoDecayHF4Prong::SelectD0 is available
@@ -1097,6 +908,7 @@ AliAODRecoDecayHF4Prong* AliAnalysisVertexingHF::Make4Prong(
   // ok4Prong=the4Prong->SelectD0(fD04pCuts,checkD0,checkD0bar); 
   ok4Prong=kFALSE;  //for the time being ...
 
+  if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) the4Prong->UnsetOwnPrimaryVtx();
 
   // get PID info from ESD
   Double_t esdpid0[5];
@@ -1110,82 +922,114 @@ AliAODRecoDecayHF4Prong* AliAnalysisVertexingHF::Make4Prong(
 
   Double_t esdpid[20];
   for(Int_t i=0;i<5;i++) {
-    esdpid[i]   = esdpid0[i];
-    esdpid[5+i] = esdpid1[i];
+    esdpid[i]    = esdpid0[i];
+    esdpid[5+i]  = esdpid1[i];
     esdpid[10+i] = esdpid2[i];
     esdpid[15+i] = esdpid3[i];
   }
   the4Prong->SetPID(4,esdpid);
 
-  if(ownPrimVertex) delete ownPrimVertex;
-
   return the4Prong;
 }
 //-----------------------------------------------------------------------------
-AliESDVertex* AliAnalysisVertexingHF::OwnPrimaryVertex(Int_t ntrks,
-                                                      TObjArray *trkArray,
-                                                      AliESDEvent *esd) const
+AliAODVertex* AliAnalysisVertexingHF::PrimaryVertex(TObjArray *trkArray,
+                                                   AliVEvent *event) const
 {
-  // Returns primary vertex specific to this candidate
+  // Returns primary vertex to be used for this candidate
  
-  AliVertexerTracks *vertexer1 = new AliVertexerTracks(esd->GetMagneticField());
-  AliESDVertex *ownPrimVertex = 0;
-
-  // recalculating the vertex
-  if(fRecoPrimVtxSkippingTrks) { 
-    if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraint")) {
-      Float_t diamondcovxy[3];
-      esd->GetDiamondCovXY(diamondcovxy);
-      Double_t pos[3]={esd->GetDiamondX(),esd->GetDiamondY(),0.};
-      Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.};
-      AliESDVertex *diamond = new AliESDVertex(pos,cov,1.,1);
-      vertexer1->SetVtxStart(diamond);
-      delete diamond; diamond=NULL;
-      if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraintOnlyFitter")) 
-       vertexer1->SetOnlyFitter();
-    }
-    Int_t skipped[10];
-    AliESDtrack *t = 0;
-    for(Int_t i=0; i<ntrks; i++) {
-      t = (AliESDtrack*)trkArray->UncheckedAt(i);
-      skipped[i] = (Int_t)t->GetID();
+  AliESDVertex *vertexESD = 0;
+  AliAODVertex *vertexAOD = 0;
+
+
+  if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) { 
+    // primary vertex from the input event
+    
+    vertexESD = new AliESDVertex(*fV1);
+
+  } else {
+    // primary vertex specific to this candidate
+
+    Int_t nTrks = trkArray->GetEntriesFast();
+    AliVertexerTracks *vertexer = new AliVertexerTracks(event->GetMagneticField());
+
+    if(fRecoPrimVtxSkippingTrks) { 
+      // recalculating the vertex
+      
+      if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraint")) {
+       Float_t diamondcovxy[3];
+       event->GetDiamondCovXY(diamondcovxy);
+       Double_t pos[3]={event->GetDiamondX(),event->GetDiamondY(),0.};
+       Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.};
+       AliESDVertex *diamond = new AliESDVertex(pos,cov,1.,1);
+       vertexer->SetVtxStart(diamond);
+       delete diamond; diamond=NULL;
+       if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraintOnlyFitter")) 
+         vertexer->SetOnlyFitter();
+      }
+      Int_t skipped[10];
+      Int_t nTrksToSkip=0,id;
+      AliExternalTrackParam *t = 0;
+      for(Int_t i=0; i<nTrks; i++) {
+       t = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
+       id = (Int_t)t->GetID();
+       if(id<0) continue;
+       skipped[nTrksToSkip++] = id;
+      }
+      vertexer->SetSkipTracks(nTrksToSkip,skipped);
+      vertexESD = (AliESDVertex*)vertexer->FindPrimaryVertex(event); 
+      
+    } else if(fRmTrksFromPrimVtx) { 
+      // removing the prongs tracks
+      
+      TObjArray rmArray(nTrks);
+      UShort_t *rmId = new UShort_t[nTrks];
+      AliESDtrack *esdTrack = 0;
+      AliESDtrack *t = 0;
+      for(Int_t i=0; i<nTrks; i++) {
+       t = (AliESDtrack*)trkArray->UncheckedAt(i);
+       esdTrack = new AliESDtrack(*t);
+       rmArray.AddLast(esdTrack);
+       if(esdTrack->GetID()>=0) {
+         rmId[i]=(UShort_t)esdTrack->GetID();
+       } else {
+         rmId[i]=9999;
+       }
+      }
+      Float_t diamondxy[2]={event->GetDiamondX(),event->GetDiamondY()};
+      vertexESD = vertexer->RemoveTracksFromVertex(fV1,&rmArray,rmId,diamondxy);
+      delete [] rmId; rmId=NULL;
+      rmArray.Delete();
+      
     }
-    vertexer1->SetSkipTracks(ntrks,skipped);
-    ownPrimVertex = (AliESDVertex*)vertexer1->FindPrimaryVertex(esd); 
-  }
 
-  // removing the prongs tracks
-  if(fRmTrksFromPrimVtx) { 
-    TObjArray rmArray(ntrks);
-    UShort_t *rmId = new UShort_t[ntrks];
-    AliESDtrack *esdTrack = 0;
-    AliESDtrack *t = 0;
-    for(Int_t i=0; i<ntrks; i++) {
-      t = (AliESDtrack*)trkArray->UncheckedAt(i);
-      esdTrack = new AliESDtrack(*t);
-      rmArray.AddLast(esdTrack);
-      rmId[i]=(UShort_t)esdTrack->GetID();
+    if(!vertexESD) return vertexAOD;
+    if(vertexESD->GetNContributors()<=0) { 
+      AliDebug(2,"vertexing failed"); 
+      delete vertexESD; vertexESD=NULL;
+      return vertexAOD;
     }
-    Float_t diamondxy[2]={esd->GetDiamondX(),esd->GetDiamondY()};
-    ownPrimVertex = vertexer1->RemoveTracksFromVertex(fV1,&rmArray,rmId,diamondxy);
-    delete [] rmId; rmId=NULL;
-    rmArray.Delete();
+
+    delete vertexer; vertexer=NULL;
+
   }
 
-  delete vertexer1; vertexer1=NULL;
+  // convert to AliAODVertex
+  Double_t pos[3],cov[6],chi2perNDF;
+  vertexESD->GetXYZ(pos); // position
+  vertexESD->GetCovMatrix(cov); //covariance matrix
+  chi2perNDF = vertexESD->GetChi2toNDF();
+  delete vertexESD; vertexESD=NULL;
+
+  vertexAOD = new AliAODVertex(pos,cov,chi2perNDF);
 
-  return ownPrimVertex;
+  return vertexAOD;
 }
 //-----------------------------------------------------------------------------
 void AliAnalysisVertexingHF::PrintStatus() const {
   // Print parameters being used
 
-  printf("Preselections:\n");
-  printf("    fITSrefit   = %d\n",(Int_t)fITSrefit);
-  printf("    fBothSPD   = %d\n",(Int_t)fBothSPD);
-  printf("    fMinITSCls   = %d\n",fMinITSCls);
-  printf("    fMinPtCut   = %f GeV/c\n",fMinPtCut);
-  printf("    fMind0rphiCut   = %f cm\n",fMind0rphiCut);
+  //printf("Preselections:\n");
+  //   fTrackFilter->Dump();
   if(fSecVtxWithKF) {
     printf("Secondary vertex with Kalman filter package (AliKFParticle)\n");
   } else {
@@ -1205,6 +1049,24 @@ void AliAnalysisVertexingHF::PrintStatus() const {
     printf("    d0d0  [cm^2] < %f\n",fD0toKpiCuts[7]);
     printf("    cosThetaPoint    > %f\n",fD0toKpiCuts[8]);
   }
+  if(fDstar) {
+    printf("    |M-MD*| [GeV]    < %f\n",fDstarCuts[0]);
+    printf("    |M_Kpipi-M_Kpi-(MD*-MD0)| [GeV]  < %f\n",fDstarCuts[1]);
+    printf("    pTpisoft [GeV/c]    > %f\n",fDstarCuts[2]);
+    printf("    pTpisoft [GeV/c]    < %f\n",fDstarCuts[3]);
+    printf("    Theta(pisoft,D0plane) < %f\n",fDstarCuts[4]);
+    printf("Reconstruct D*->D0pi candidates with cuts:\n");
+    printf("   D0 from D* cuts:\n");
+    printf("    |M-MD0| [GeV]    < %f\n",fD0fromDstarCuts[0]);
+    printf("    dca    [cm]  < %f\n",fD0fromDstarCuts[1]);
+    printf("    cosThetaStar     < %f\n",fD0fromDstarCuts[2]);
+    printf("    pTK     [GeV/c]    > %f\n",fD0fromDstarCuts[3]);
+    printf("    pTpi    [GeV/c]    > %f\n",fD0fromDstarCuts[4]);
+    printf("    |d0K|  [cm]  < %f\n",fD0fromDstarCuts[5]);
+    printf("    |d0pi| [cm]  < %f\n",fD0fromDstarCuts[6]);
+    printf("    d0d0  [cm^2] < %f\n",fD0fromDstarCuts[7]);
+    printf("    cosThetaPoint    > %f\n",fD0fromDstarCuts[8]);
+  }
   if(fJPSItoEle) {
     printf("Reconstruct J/psi from B candidates with cuts:\n");
     printf("    |M-MJPSI| [GeV]    < %f\n",fBtoJPSICuts[0]);
@@ -1265,6 +1127,62 @@ void AliAnalysisVertexingHF::PrintStatus() const {
   return;
 }
 //-----------------------------------------------------------------------------
+AliAODVertex* AliAnalysisVertexingHF::ReconstructSecondaryVertex(TObjArray *trkArray,
+                                                                Double_t &dispersion,Bool_t useTRefArray) const
+{
+  // Secondary vertex reconstruction with AliVertexerTracks or AliKFParticle
+
+  AliESDVertex *vertexESD = 0;
+  AliAODVertex *vertexAOD = 0;
+
+  if(!fSecVtxWithKF) { // AliVertexerTracks
+
+    AliVertexerTracks *vertexer = new AliVertexerTracks(fBzkG);
+    vertexer->SetVtxStart(fV1);
+    vertexESD = (AliESDVertex*)vertexer->VertexForSelectedESDTracks(trkArray);
+    delete vertexer; vertexer=NULL;
+
+    if(!vertexESD) return vertexAOD;
+
+    if(vertexESD->GetNContributors()!=trkArray->GetEntriesFast()) { 
+      AliDebug(2,"vertexing failed"); 
+      delete vertexESD; vertexESD=NULL;
+      return vertexAOD;
+    }
+
+  } else { // Kalman Filter vertexer (AliKFParticle)
+
+    AliKFParticle::SetField(fBzkG);
+
+    AliKFVertex vertexKF;
+
+    Int_t nTrks = trkArray->GetEntriesFast();
+    for(Int_t i=0; i<nTrks; i++) {
+      AliESDtrack *esdTrack = (AliESDtrack*)trkArray->At(i);
+      AliKFParticle daughterKF(*esdTrack,211);
+      vertexKF.AddDaughter(daughterKF);
+    }
+    vertexESD = new AliESDVertex(vertexKF.Parameters(),
+                                vertexKF.CovarianceMatrix(),
+                                vertexKF.GetChi2(),
+                                vertexKF.GetNContributors());
+
+  }
+
+  // convert to AliAODVertex
+  Double_t pos[3],cov[6],chi2perNDF;
+  vertexESD->GetXYZ(pos); // position
+  vertexESD->GetCovMatrix(cov); //covariance matrix
+  chi2perNDF = vertexESD->GetChi2toNDF();
+  dispersion = vertexESD->GetDispersion();
+  delete vertexESD; vertexESD=NULL;
+
+  Int_t nprongs= (useTRefArray ? 0 : trkArray->GetEntriesFast());
+  vertexAOD = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,nprongs);
+
+  return vertexAOD;
+}
+//-----------------------------------------------------------------------------
 Bool_t AliAnalysisVertexingHF::SelectInvMass(Int_t decay,
                                             Int_t nprongs,
                                             Double_t *px,
@@ -1321,7 +1239,14 @@ Bool_t AliAnalysisVertexingHF::SelectInvMass(Int_t decay,
       minv = rd->InvMass(nprongs,pdg3);
       if(TMath::Abs(minv-mPDG)<fLcCuts[0]) retval=kTRUE; 
       break;
+    case 3:                  // D*->D0pi
+      pdg2[0]=421; pdg2[1]=211;
+      mPDG=TDatabasePDG::Instance()->GetParticle(413)->Mass();
+      minv = rd->InvMass(nprongs,pdg2);
+      if(TMath::Abs(minv-mPDG)<fDstarCuts[0]) retval=kTRUE;
+      break;
     default:
+      printf("SelectInvMass(): wrong decay selection\n");
       break;
     }
 
@@ -1330,51 +1255,90 @@ Bool_t AliAnalysisVertexingHF::SelectInvMass(Int_t decay,
   return retval;
 }
 //-----------------------------------------------------------------------------
-void AliAnalysisVertexingHF::SelectTracks(AliESDEvent *esd,
-                                         TObjArray &trksP,Int_t &nTrksP,
-                                         TObjArray &trksN,Int_t &nTrksN) const
+void AliAnalysisVertexingHF::SelectTracksAndCopyVertex(AliVEvent *event,
+                                  TObjArray &seleTrksArray,Int_t &nSeleTrks,
+                                                      UChar_t *seleFlags)
 {
-  // Fill two TObjArrays with positive and negative tracks and 
-  // apply single-track preselection
+  // Apply single-track preselection.
+  // Fill a TObjArray with selected tracks (for displaced vertices or
+  // soft pion from D*). Selection flag stored in seleFlags.
+  // Create the AliESDVertex object (convert from AliAODVertex if necessary)
+  // In case of AOD input, also fill fAODMap for track index<->ID
+
+  const AliVVertex *vprimary = event->GetPrimaryVertex();
 
-  nTrksP=0,nTrksN=0;
+  if(fV1) { delete fV1; fV1=NULL; }
+  if(fAODMap) { delete [] fAODMap; fAODMap=NULL; }
 
-  Int_t entries = (Int_t)esd->GetNumberOfTracks();
+  Int_t nindices=0;
+  UShort_t *indices = 0;
+  Double_t pos[3],cov[6];
+
+  if(!fInputAOD) { // ESD
+    fV1 = new AliESDVertex(*((AliESDVertex*)vprimary));
+  } else {         // AOD
+    vprimary->GetXYZ(pos);
+    vprimary->GetCovarianceMatrix(cov);
+    fV1 = new AliESDVertex(pos,cov,100.,100,vprimary->GetName());
+    indices = new UShort_t[event->GetNumberOfTracks()];
+    fAODMap = new Int_t[100000];
+  }
+
+
+  Int_t entries = (Int_t)event->GetNumberOfTracks();
+  Bool_t okDisplaced=kFALSE,okSoftPi=kFALSE;
+  nSeleTrks=0;
  
-  // transfer ITS tracks from ESD to arrays and to a tree
+  // transfer ITS tracks from event to arrays
   for(Int_t i=0; i<entries; i++) {
+    AliVTrack *track = (AliVTrack*)event->GetTrack(i);
 
-    AliESDtrack *esdtrack = esd->GetTrack(i);
-    UInt_t status = esdtrack->GetStatus();
-
-    // require refit in ITS 
-    if(fITSrefit && !(status&AliESDtrack::kITSrefit)) {
-      if(fDebug) printf("track %d is not kITSrefit\n",i);
-      continue;
+    if(fInputAOD) {
+      AliAODTrack *aodt = (AliAODTrack*)track;
+      if(aodt->GetUsedForPrimVtxFit()) { 
+       indices[nindices]=aodt->GetID(); nindices++; 
+      }
+      fAODMap[(Int_t)aodt->GetID()] = i;
     }
 
-    // require minimum # of ITS points    
-    if(esdtrack->GetNcls(0)<fMinITSCls)  {
-      if(fDebug) printf("track %d has %d ITS cls\n",i,esdtrack->GetNcls(0));
-      continue;
+    AliESDtrack *esdt = 0;
+    if(!fInputAOD) {
+      esdt = (AliESDtrack*)track;
+    } else {
+      esdt = new AliESDtrack(track);
     }
-    // require points on the 2 pixel layers
-    if(fBothSPD) 
-      if(!TESTBIT(esdtrack->GetITSClusterMap(),0) || 
-        !TESTBIT(esdtrack->GetITSClusterMap(),1)) continue;
 
     // single track selection
-    if(!SingleTrkCuts(*esdtrack)) continue;
-
-    if(esdtrack->GetSign()<0) { // negative track
-      trksN.AddLast(esdtrack);
-      nTrksN++;
-    } else {                 // positive track
-      trksP.AddLast(esdtrack);
-      nTrksP++;
-    }
+    okDisplaced=kFALSE; okSoftPi=kFALSE;
+    if(SingleTrkCuts(esdt,okDisplaced,okSoftPi)) {
+      seleTrksArray.AddLast(esdt);
+      seleFlags[nSeleTrks]=0;
+      if(okDisplaced) SETBIT(seleFlags[nSeleTrks],kBitDispl);
+      if(okSoftPi)    SETBIT(seleFlags[nSeleTrks],kBitSoftPi);
+      nSeleTrks++;
+    } else {
+      if(fInputAOD) delete esdt; 
+      esdt = NULL;
+      continue;
+    } 
+
+  } // end loop on tracks
+
+  // primary vertex from AOD
+  if(fInputAOD) {
+    delete fV1; fV1=NULL;
+    vprimary->GetXYZ(pos);
+    vprimary->GetCovarianceMatrix(cov);
+    Double_t chi2toNDF = vprimary->GetChi2perNDF();
+    Int_t ncontr=nindices;
+    if(!strcmp(vprimary->GetTitle(),"VertexerTracksWithContraint")) ncontr += 1;
+    Double_t chi2=chi2toNDF*(2.*(Double_t)ncontr-3.); 
+    fV1 = new AliESDVertex(pos,cov,chi2,ncontr,vprimary->GetName());
+    fV1->SetTitle(vprimary->GetTitle());
+    fV1->SetIndices(nindices,indices);
+  }
+  if(indices) { delete [] indices; indices=NULL; }
 
-  } // loop on ESD tracks
 
   return;
 }
@@ -1407,6 +1371,57 @@ void AliAnalysisVertexingHF::SetD0toKpiCuts(const Double_t cuts[9])
   return;
 }
 //-----------------------------------------------------------------------------
+void AliAnalysisVertexingHF::SetD0fromDstarCuts(Double_t cut0,Double_t cut1,
+                                  Double_t cut2,Double_t cut3,Double_t cut4,
+                                  Double_t cut5,Double_t cut6,
+                                  Double_t cut7,Double_t cut8) 
+{
+  // Set the cuts for D0 from D* selection
+  fD0fromDstarCuts[0] = cut0;
+  fD0fromDstarCuts[1] = cut1;
+  fD0fromDstarCuts[2] = cut2;
+  fD0fromDstarCuts[3] = cut3;
+  fD0fromDstarCuts[4] = cut4;
+  fD0fromDstarCuts[5] = cut5;
+  fD0fromDstarCuts[6] = cut6;
+  fD0fromDstarCuts[7] = cut7;
+  fD0fromDstarCuts[8] = cut8;
+
+  return;
+}
+//-----------------------------------------------------------------------------
+void AliAnalysisVertexingHF::SetD0fromDstarCuts(const Double_t cuts[9]) 
+{
+  // Set the cuts for D0 from D* selection
+
+  for(Int_t i=0; i<9; i++) fD0fromDstarCuts[i] = cuts[i];
+
+  return;
+}
+//-----------------------------------------------------------------------------
+void AliAnalysisVertexingHF::SetDstarCuts(Double_t cut0,Double_t cut1,
+                                          Double_t cut2,Double_t cut3,
+                                          Double_t cut4)
+{
+  // Set the cuts for D* selection
+  fDstarCuts[0] = cut0;
+  fDstarCuts[1] = cut1;
+  fDstarCuts[2] = cut2;
+  fDstarCuts[3] = cut3;
+  fDstarCuts[4] = cut4;
+
+  return;
+}
+//-----------------------------------------------------------------------------
+void AliAnalysisVertexingHF::SetDstarCuts(const Double_t cuts[5])
+{
+  // Set the cuts for D* selection
+
+  for(Int_t i=0; i<5; i++) fDstarCuts[i] = cuts[i];
+
+  return;
+}
+//-----------------------------------------------------------------------------
 void AliAnalysisVertexingHF::SetBtoJPSICuts(Double_t cut0,Double_t cut1,
                                   Double_t cut2,Double_t cut3,Double_t cut4,
                                   Double_t cut5,Double_t cut6,
@@ -1533,64 +1548,31 @@ void AliAnalysisVertexingHF::SetLcCuts(const Double_t cuts[12])
   return;
 }
 //-----------------------------------------------------------------------------
-Bool_t AliAnalysisVertexingHF::SingleTrkCuts(AliESDtrack& trk) const 
+Bool_t AliAnalysisVertexingHF::SingleTrkCuts(AliESDtrack *trk,
+                                            Bool_t &okDisplaced,Bool_t &okSoftPi) const 
 {
   // Check if track passes some kinematical cuts  
 
-  if(TMath::Abs(trk.Pt()) < fMinPtCut) {
-    //printf("pt %f\n",1./trk.GetParameter()[4]);
-    return kFALSE;
+  // this is needed to store the impact parameters
+  trk->RelateToVertex(fV1,fBzkG,kVeryBig);
+
+  UInt_t selectInfo;
+  //
+  // Track selection, displaced tracks
+  selectInfo = 0; 
+  if(fTrackFilter) {
+    selectInfo = fTrackFilter->IsSelected(trk);
   }
-  trk.RelateToVertex(fV1,fBzkG,10.);
-  Float_t d0z0[2],covd0z0[3];
-  trk.GetImpactParameters(d0z0,covd0z0);
-  if(TMath::Abs(d0z0[0]) < fMind0rphiCut) {
-    printf("d0rphi %f\n",TMath::Abs(d0z0[0]));
-    return kFALSE;
+  if(selectInfo) okDisplaced=kTRUE;
+  // Track selection, soft pions
+  selectInfo = 0; 
+  if(fDstar && fTrackFilterSoftPi) {
+    selectInfo = fTrackFilterSoftPi->IsSelected(trk);
   }
+  if(selectInfo) okSoftPi=kTRUE;
 
-  return kTRUE;
-}
-//-----------------------------------------------------------------------------
-AliESDVertex* AliAnalysisVertexingHF::ReconstructSecondaryVertex(TObjArray *trkArray) const
-{
-  // Secondary vertex reconstruction with AliVertexerTracks or AliKFParticle
-
-  AliESDVertex *vertex = 0;
+  if(okDisplaced || okSoftPi) return kTRUE;
 
-  if(!fSecVtxWithKF) { // AliVertexerTracks
-
-    AliVertexerTracks *vertexer2 = new AliVertexerTracks(fBzkG);
-    vertexer2->SetDebug(0);
-    vertexer2->SetVtxStart(fV1);
-    vertex = (AliESDVertex*)vertexer2->VertexForSelectedESDTracks(trkArray);
-    delete vertexer2;
-
-    if(vertex->GetNContributors()!=trkArray->GetEntriesFast()) { 
-      if(fDebug) printf("vertexing failed\n"); 
-      delete vertex; vertex=0;
-    }
-
-  } else { // Kalman Filter vertexer (AliKFParticle)
-
-    AliKFParticle::SetField(fBzkG);
-
-    AliKFParticle vertexKF;
-
-    Int_t nTrks = trkArray->GetEntriesFast();
-    for(Int_t i=0; i<nTrks; i++) {
-      AliESDtrack *esdTrack = (AliESDtrack*)trkArray->At(i);
-      AliKFParticle daughterKF(*esdTrack,211);
-      vertexKF.AddDaughter(daughterKF);
-    }
-    vertex = new AliESDVertex();
-    vertexKF.CopyToESDVertex(*vertex);
-
-  }
-
-  return vertex;
+  return kFALSE;
 }
 //-----------------------------------------------------------------------------
-
-
-