1 /**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 //----------------------------------------------------------------------------
17 // Implementation of the heavy-flavour vertexing analysis class
18 // Candidates are stored in the AOD as objects deriving from AliAODRecoDecay.
19 // To be used as a task of AliAnalysisManager by means of the interface
20 // class AliAnalysisTaskSEVertexingHF.
21 // An example of usage in the macro AliAnalysisTaskSEVertexingHFTest.C.
23 // Contact: andrea.dainese@pd.infn.it
24 // Contributors: E.Bruna, G.E.Bruno, A.Dainese, C.Di Gliglio,
25 // F.Prino, R.Romita, X.M.Zhang
26 //----------------------------------------------------------------------------
27 #include <Riostream.h>
29 #include <TDatabasePDG.h>
33 #include "AliVEvent.h"
34 #include "AliVVertex.h"
35 #include "AliVTrack.h"
36 #include "AliVertexerTracks.h"
37 #include "AliKFVertex.h"
38 #include "AliESDEvent.h"
39 #include "AliESDVertex.h"
40 #include "AliExternalTrackParam.h"
41 #include "AliNeutralTrackParam.h"
42 #include "AliESDtrack.h"
43 #include "AliESDtrackCuts.h"
44 #include "AliAODEvent.h"
45 #include "AliAODRecoDecay.h"
46 #include "AliAODRecoDecayHF.h"
47 #include "AliAODRecoDecayHF2Prong.h"
48 #include "AliAODRecoDecayHF3Prong.h"
49 #include "AliAODRecoDecayHF4Prong.h"
50 #include "AliAODRecoCascadeHF.h"
51 #include "AliRDHFCutsD0toKpi.h"
52 #include "AliRDHFCutsJpsitoee.h"
53 #include "AliRDHFCutsDplustoKpipi.h"
54 #include "AliRDHFCutsDstoKKpi.h"
55 #include "AliRDHFCutsLctopKpi.h"
56 #include "AliRDHFCutsLctoV0.h"
57 #include "AliRDHFCutsD0toKpipipi.h"
58 #include "AliRDHFCutsDStartoKpipi.h"
59 #include "AliAnalysisFilter.h"
60 #include "AliAnalysisVertexingHF.h"
61 #include "AliMixedEvent.h"
65 ClassImp(AliAnalysisVertexingHF)
67 //----------------------------------------------------------------------------
68 AliAnalysisVertexingHF::AliAnalysisVertexingHF():
73 fSecVtxWithKF(kFALSE),
74 fRecoPrimVtxSkippingTrks(kFALSE),
75 fRmTrksFromPrimVtx(kFALSE),
86 fTrackFilterSoftPi(0x0),
89 fCutsDplustoKpipi(0x0),
93 fCutsD0toKpipipi(0x0),
94 fCutsDStartoKpipi(0x0),
96 fFindVertexForDstar(kTRUE),
97 fFindVertexForCascades(kTRUE),
98 fMassCutBeforeVertexing(kFALSE),
103 // Default constructor
105 Double_t d02[2],d03[3],d04[4];
106 fMassCalc2 = new AliAODRecoDecay(0x0,2,0,d02);
107 fMassCalc3 = new AliAODRecoDecay(0x0,3,1,d03);
108 fMassCalc4 = new AliAODRecoDecay(0x0,4,0,d04);
111 //--------------------------------------------------------------------------
112 AliAnalysisVertexingHF::AliAnalysisVertexingHF(const AliAnalysisVertexingHF &source) :
114 fInputAOD(source.fInputAOD),
115 fAODMapSize(source.fAODMapSize),
116 fAODMap(source.fAODMap),
118 fSecVtxWithKF(source.fSecVtxWithKF),
119 fRecoPrimVtxSkippingTrks(source.fRecoPrimVtxSkippingTrks),
120 fRmTrksFromPrimVtx(source.fRmTrksFromPrimVtx),
122 fD0toKpi(source.fD0toKpi),
123 fJPSItoEle(source.fJPSItoEle),
124 f3Prong(source.f3Prong),
125 f4Prong(source.f4Prong),
126 fDstar(source.fDstar),
127 fCascades(source.fCascades),
128 fLikeSign(source.fLikeSign),
129 fMixEvent(source.fMixEvent),
130 fTrackFilter(source.fTrackFilter),
131 fTrackFilterSoftPi(source.fTrackFilterSoftPi),
132 fCutsD0toKpi(source.fCutsD0toKpi),
133 fCutsJpsitoee(source.fCutsJpsitoee),
134 fCutsDplustoKpipi(source.fCutsDplustoKpipi),
135 fCutsDstoKKpi(source.fCutsDstoKKpi),
136 fCutsLctopKpi(source.fCutsLctopKpi),
137 fCutsLctoV0(source.fCutsLctoV0),
138 fCutsD0toKpipipi(source.fCutsD0toKpipipi),
139 fCutsDStartoKpipi(source.fCutsDStartoKpipi),
140 fListOfCuts(source.fListOfCuts),
141 fFindVertexForDstar(source.fFindVertexForDstar),
142 fFindVertexForCascades(source.fFindVertexForCascades),
143 fMassCutBeforeVertexing(source.fMassCutBeforeVertexing),
144 fMassCalc2(source.fMassCalc2),
145 fMassCalc3(source.fMassCalc3),
146 fMassCalc4(source.fMassCalc4)
152 //--------------------------------------------------------------------------
153 AliAnalysisVertexingHF &AliAnalysisVertexingHF::operator=(const AliAnalysisVertexingHF &source)
156 // assignment operator
158 if(&source == this) return *this;
159 fInputAOD = source.fInputAOD;
160 fAODMapSize = source.fAODMapSize;
161 fBzkG = source.fBzkG;
162 fSecVtxWithKF = source.fSecVtxWithKF;
163 fRecoPrimVtxSkippingTrks = source.fRecoPrimVtxSkippingTrks;
164 fRmTrksFromPrimVtx = source.fRmTrksFromPrimVtx;
166 fD0toKpi = source.fD0toKpi;
167 fJPSItoEle = source.fJPSItoEle;
168 f3Prong = source.f3Prong;
169 f4Prong = source.f4Prong;
170 fDstar = source.fDstar;
171 fCascades = source.fCascades;
172 fLikeSign = source.fLikeSign;
173 fMixEvent = source.fMixEvent;
174 fTrackFilter = source.fTrackFilter;
175 fTrackFilterSoftPi = source.fTrackFilterSoftPi;
176 fCutsD0toKpi = source.fCutsD0toKpi;
177 fCutsJpsitoee = source.fCutsJpsitoee;
178 fCutsDplustoKpipi = source.fCutsDplustoKpipi;
179 fCutsDstoKKpi = source.fCutsDstoKKpi;
180 fCutsLctopKpi = source.fCutsLctopKpi;
181 fCutsLctoV0 = source.fCutsLctoV0;
182 fCutsD0toKpipipi = source.fCutsD0toKpipipi;
183 fCutsDStartoKpipi = source.fCutsDStartoKpipi;
184 fListOfCuts = source.fListOfCuts;
185 fFindVertexForDstar = source.fFindVertexForDstar;
186 fFindVertexForCascades = source.fFindVertexForCascades;
187 fMassCutBeforeVertexing = source.fMassCutBeforeVertexing;
188 fMassCalc2 = source.fMassCalc2;
189 fMassCalc3 = source.fMassCalc3;
190 fMassCalc4 = source.fMassCalc4;
194 //----------------------------------------------------------------------------
195 AliAnalysisVertexingHF::~AliAnalysisVertexingHF() {
197 if(fV1) { delete fV1; fV1=0; }
198 if(fTrackFilter) { delete fTrackFilter; fTrackFilter=0; }
199 if(fTrackFilterSoftPi) { delete fTrackFilterSoftPi; fTrackFilterSoftPi=0; }
200 if(fCutsD0toKpi) { delete fCutsD0toKpi; fCutsD0toKpi=0; }
201 if(fCutsJpsitoee) { delete fCutsJpsitoee; fCutsJpsitoee=0; }
202 if(fCutsDplustoKpipi) { delete fCutsDplustoKpipi; fCutsDplustoKpipi=0; }
203 if(fCutsDstoKKpi) { delete fCutsDstoKKpi; fCutsDstoKKpi=0; }
204 if(fCutsLctopKpi) { delete fCutsLctopKpi; fCutsLctopKpi=0; }
205 if(fCutsLctoV0) { delete fCutsLctoV0; fCutsLctoV0=0; }
206 if(fCutsD0toKpipipi) { delete fCutsD0toKpipipi; fCutsD0toKpipipi=0; }
207 if(fCutsDStartoKpipi) { delete fCutsDStartoKpipi; fCutsDStartoKpipi=0; }
208 if(fAODMap) { delete fAODMap; fAODMap=0; }
209 if(fMassCalc2) { delete fMassCalc2; fMassCalc2=0; }
210 if(fMassCalc3) { delete fMassCalc3; fMassCalc3=0; }
211 if(fMassCalc4) { delete fMassCalc4; fMassCalc4=0; }
213 //----------------------------------------------------------------------------
214 TList *AliAnalysisVertexingHF::FillListOfCuts() {
215 // Fill list of analysis cuts
217 TList *list = new TList();
219 list->SetName("ListOfCuts");
222 AliRDHFCutsD0toKpi *cutsD0toKpi = new AliRDHFCutsD0toKpi(*fCutsD0toKpi);
223 list->Add(cutsD0toKpi);
226 AliRDHFCutsJpsitoee *cutsJpsitoee = new AliRDHFCutsJpsitoee(*fCutsJpsitoee);
227 list->Add(cutsJpsitoee);
229 if(fCutsDplustoKpipi) {
230 AliRDHFCutsDplustoKpipi *cutsDplustoKpipi = new AliRDHFCutsDplustoKpipi(*fCutsDplustoKpipi);
231 list->Add(cutsDplustoKpipi);
234 AliRDHFCutsDstoKKpi *cutsDstoKKpi = new AliRDHFCutsDstoKKpi(*fCutsDstoKKpi);
235 list->Add(cutsDstoKKpi);
238 AliRDHFCutsLctopKpi *cutsLctopKpi = new AliRDHFCutsLctopKpi(*fCutsLctopKpi);
239 list->Add(cutsLctopKpi);
242 AliRDHFCutsLctoV0 *cutsLctoV0 = new AliRDHFCutsLctoV0(*fCutsLctoV0);
243 list->Add(cutsLctoV0);
245 if(fCutsD0toKpipipi) {
246 AliRDHFCutsD0toKpipipi *cutsD0toKpipipi = new AliRDHFCutsD0toKpipipi(*fCutsD0toKpipipi);
247 list->Add(cutsD0toKpipipi);
249 if(fCutsDStartoKpipi) {
250 AliRDHFCutsDStartoKpipi *cutsDStartoKpipi = new AliRDHFCutsDStartoKpipi(*fCutsDStartoKpipi);
251 list->Add(cutsDStartoKpipi);
254 // keep a pointer to the list
259 //----------------------------------------------------------------------------
260 void AliAnalysisVertexingHF::FindCandidates(AliVEvent *event,
261 TClonesArray *aodVerticesHFTClArr,
262 TClonesArray *aodD0toKpiTClArr,
263 TClonesArray *aodJPSItoEleTClArr,
264 TClonesArray *aodCharm3ProngTClArr,
265 TClonesArray *aodCharm4ProngTClArr,
266 TClonesArray *aodDstarTClArr,
267 TClonesArray *aodCascadesTClArr,
268 TClonesArray *aodLikeSign2ProngTClArr,
269 TClonesArray *aodLikeSign3ProngTClArr)
271 // Find heavy-flavour vertex candidates
273 // Output: AOD (additional branches added)
276 TString evtype = event->IsA()->GetName();
277 fInputAOD = ((evtype=="AliAODEvent") ? kTRUE : kFALSE);
278 } // if we do mixing AliVEvent is a AliMixedEvent
281 AliDebug(2,"Creating HF candidates from AOD");
283 AliDebug(2,"Creating HF candidates from ESD");
286 if(!aodVerticesHFTClArr) {
287 printf("ERROR: no aodVerticesHFTClArr");
290 if((fD0toKpi || fDstar) && !aodD0toKpiTClArr) {
291 printf("ERROR: no aodD0toKpiTClArr");
294 if(fJPSItoEle && !aodJPSItoEleTClArr) {
295 printf("ERROR: no aodJPSItoEleTClArr");
298 if(f3Prong && !aodCharm3ProngTClArr) {
299 printf("ERROR: no aodCharm3ProngTClArr");
302 if(f4Prong && !aodCharm4ProngTClArr) {
303 printf("ERROR: no aodCharm4ProngTClArr");
306 if(fDstar && !aodDstarTClArr) {
307 printf("ERROR: no aodDstarTClArr");
310 if(fCascades && !aodCascadesTClArr){
311 printf("ERROR: no aodCascadesTClArr ");
314 if(fLikeSign && !aodLikeSign2ProngTClArr) {
315 printf("ERROR: no aodLikeSign2ProngTClArr");
318 if(fLikeSign && f3Prong && !aodLikeSign3ProngTClArr) {
319 printf("ERROR: no aodLikeSign2ProngTClArr");
323 // delete candidates from previous event and create references
324 Int_t iVerticesHF=0,iD0toKpi=0,iJPSItoEle=0,i3Prong=0,i4Prong=0,iDstar=0,iCascades=0,iLikeSign2Prong=0,iLikeSign3Prong=0;
325 aodVerticesHFTClArr->Delete();
326 iVerticesHF = aodVerticesHFTClArr->GetEntriesFast();
327 TClonesArray &verticesHFRef = *aodVerticesHFTClArr;
328 if(fD0toKpi || fDstar) {
329 aodD0toKpiTClArr->Delete();
330 iD0toKpi = aodD0toKpiTClArr->GetEntriesFast();
333 aodJPSItoEleTClArr->Delete();
334 iJPSItoEle = aodJPSItoEleTClArr->GetEntriesFast();
337 aodCharm3ProngTClArr->Delete();
338 i3Prong = aodCharm3ProngTClArr->GetEntriesFast();
341 aodCharm4ProngTClArr->Delete();
342 i4Prong = aodCharm4ProngTClArr->GetEntriesFast();
345 aodDstarTClArr->Delete();
346 iDstar = aodDstarTClArr->GetEntriesFast();
349 aodCascadesTClArr->Delete();
350 iCascades = aodCascadesTClArr->GetEntriesFast();
353 aodLikeSign2ProngTClArr->Delete();
354 iLikeSign2Prong = aodLikeSign2ProngTClArr->GetEntriesFast();
356 if(fLikeSign && f3Prong) {
357 aodLikeSign3ProngTClArr->Delete();
358 iLikeSign3Prong = aodLikeSign3ProngTClArr->GetEntriesFast();
361 TClonesArray &aodD0toKpiRef = *aodD0toKpiTClArr;
362 TClonesArray &aodJPSItoEleRef = *aodJPSItoEleTClArr;
363 TClonesArray &aodCharm3ProngRef = *aodCharm3ProngTClArr;
364 TClonesArray &aodCharm4ProngRef = *aodCharm4ProngTClArr;
365 TClonesArray &aodDstarRef = *aodDstarTClArr;
366 TClonesArray &aodCascadesRef = *aodCascadesTClArr;
367 TClonesArray &aodLikeSign2ProngRef = *aodLikeSign2ProngTClArr;
368 TClonesArray &aodLikeSign3ProngRef = *aodLikeSign3ProngTClArr;
371 AliAODRecoDecayHF2Prong *io2Prong = 0;
372 AliAODRecoDecayHF3Prong *io3Prong = 0;
373 AliAODRecoDecayHF4Prong *io4Prong = 0;
374 AliAODRecoCascadeHF *ioCascade = 0;
376 Int_t iTrkP1,iTrkP2,iTrkN1,iTrkN2,iTrkSoftPi,trkEntries,iv0,nv0;
377 Double_t xdummy,ydummy,dcap1n1,dcap1n2,dcap2n1,dcap1p2,dcan1n2,dcap2n2,dcaV0,dcaCasc;
378 Bool_t okD0=kFALSE,okJPSI=kFALSE,ok3Prong=kFALSE,ok4Prong=kFALSE;
379 Bool_t okDstar=kFALSE,okD0fromDstar=kFALSE;
380 Bool_t okCascades=kFALSE;
381 AliESDtrack *postrack1 = 0;
382 AliESDtrack *postrack2 = 0;
383 AliESDtrack *negtrack1 = 0;
384 AliESDtrack *negtrack2 = 0;
385 AliESDtrack *trackPi = 0;
386 // AliESDtrack *posV0track = 0;
387 // AliESDtrack *negV0track = 0;
388 Float_t dcaMax = fCutsD0toKpi->GetDCACut();
389 if(fCutsJpsitoee) dcaMax=TMath::Max(dcaMax,fCutsJpsitoee->GetDCACut());
390 if(fCutsDplustoKpipi) dcaMax=TMath::Max(dcaMax,fCutsDplustoKpipi->GetDCACut());
391 if(fCutsDstoKKpi) dcaMax=TMath::Max(dcaMax,fCutsDstoKKpi->GetDCACut());
392 if(fCutsLctopKpi) dcaMax=TMath::Max(dcaMax,fCutsLctopKpi->GetDCACut());
393 if(fCutsD0toKpipipi) dcaMax=TMath::Max(dcaMax,fCutsD0toKpipipi->GetDCACut());
394 if(fCutsDStartoKpipi) dcaMax=TMath::Max(dcaMax,fCutsDStartoKpipi->GetDCACut());
396 AliDebug(2,Form(" dca cut set to %f cm",dcaMax));
400 fBzkG = (Double_t)event->GetMagneticField();
402 trkEntries = (Int_t)event->GetNumberOfTracks();
403 AliDebug(1,Form(" Number of tracks: %d",trkEntries));
405 nv0 = (Int_t)event->GetNumberOfV0s();
406 AliDebug(1,Form(" Number of V0s: %d",nv0));
408 if( trkEntries<2 && (trkEntries<1 || nv0<1) ) {
409 AliDebug(1,Form(" Not enough tracks: %d",trkEntries));
414 if(!fCutsD0toKpi->IsEventSelected(event)) return;
416 // call function that applies sigle-track selection,
417 // for displaced tracks and soft pions (both charges) for D*,
418 // and retrieves primary vertex
419 TObjArray seleTrksArray(trkEntries);
420 UChar_t *seleFlags = new UChar_t[trkEntries]; // bit 0: displaced, bit 1: softpi
422 Int_t *evtNumber = new Int_t[trkEntries];
423 SelectTracksAndCopyVertex(event,trkEntries,seleTrksArray,nSeleTrks,seleFlags,evtNumber);
425 //AliDebug(1,Form(" Selected tracks: %d",nSeleTrks));
426 printf(" Selected tracks: %d\n",nSeleTrks);
428 TObjArray *twoTrackArray1 = new TObjArray(2);
429 TObjArray *twoTrackArray2 = new TObjArray(2);
430 TObjArray *twoTrackArrayV0 = new TObjArray(2);
431 TObjArray *twoTrackArrayCasc = new TObjArray(2);
432 TObjArray *threeTrackArray = new TObjArray(3);
433 TObjArray *fourTrackArray = new TObjArray(4);
436 Bool_t isLikeSign2Prong=kFALSE,isLikeSign3Prong=kFALSE;
438 AliAODRecoDecayHF *rd = 0;
439 AliAODRecoCascadeHF *rc = 0;
443 Bool_t massCutOK=kTRUE;
445 // LOOP ON POSITIVE TRACKS
446 for(iTrkP1=0; iTrkP1<nSeleTrks; iTrkP1++) {
448 if(iTrkP1%1==0) AliDebug(1,Form(" 1st loop on pos: track number %d of %d",iTrkP1,nSeleTrks));
449 //if(iTrkP1%1==0) printf(" 1st loop on pos: track number %d of %d\n",iTrkP1,nSeleTrks);
451 // get track from tracks array
452 postrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP1);
454 if(!TESTBIT(seleFlags[iTrkP1],kBitDispl)) continue;
456 // Make cascades with V0+track
460 for(iv0=0; iv0<nv0; iv0++){
462 AliDebug(1,Form(" loop on v0s for track number %d and v0 number %d",iTrkP1,iv0));
466 v0 = ((AliAODEvent*)event)->GetV0(iv0);
468 esdV0 = ((AliESDEvent*)event)->GetV0(iv0);
470 if ( (!v0 || !v0->IsA()->InheritsFrom("AliAODv0") ) &&
471 (!esdV0 || !esdV0->IsA()->InheritsFrom("AliESDv0") ) ) continue;
474 // Get the tracks that form the V0
475 // ( parameters at primary vertex )
476 // and define an AliExternalTrackParam out of them
477 AliExternalTrackParam * posV0track;
478 AliExternalTrackParam * negV0track;
481 AliAODTrack *posVV0track = (AliAODTrack*)(v0->GetDaughter(0));
482 AliAODTrack *negVV0track = (AliAODTrack*)(v0->GetDaughter(1));
483 if( !posVV0track || !negVV0track ) continue;
485 // Apply some basic V0 daughter criteria
487 // bachelor must not be a v0-track
488 if (posVV0track->GetID() == postrack1->GetID() ||
489 negVV0track->GetID() == postrack1->GetID()) continue;
490 // reject like-sign v0
491 if ( posVV0track->Charge() == negVV0track->Charge() ) continue;
492 // avoid ghost TPC tracks
493 if(!(posVV0track->GetStatus() & AliESDtrack::kTPCrefit) ||
494 !(negVV0track->GetStatus() & AliESDtrack::kTPCrefit)) continue;
495 // Get AliExternalTrackParam out of the AliAODTracks
496 Double_t xyz[3], pxpypz[3], cv[21]; Short_t sign;
497 posVV0track->PxPyPz(pxpypz); posVV0track->XvYvZv(xyz);
498 posVV0track->GetCovarianceXYZPxPyPz(cv); sign=posVV0track->Charge();
499 posV0track = new AliExternalTrackParam(xyz,pxpypz,cv,sign);
500 negVV0track->PxPyPz(pxpypz); negVV0track->XvYvZv(xyz);
501 negVV0track->GetCovarianceXYZPxPyPz(cv); sign=negVV0track->Charge();
502 negV0track = new AliExternalTrackParam(xyz,pxpypz,cv,sign);
504 AliESDtrack *posVV0track = (AliESDtrack*)(event->GetTrack( esdV0->GetPindex() ));
505 AliESDtrack *negVV0track = (AliESDtrack*)(event->GetTrack( esdV0->GetNindex() ));
506 if( !posVV0track || !negVV0track ) continue;
508 // Apply some basic V0 daughter criteria
510 // bachelor must not be a v0-track
511 if (posVV0track->GetID() == postrack1->GetID() ||
512 negVV0track->GetID() == postrack1->GetID()) continue;
513 // reject like-sign v0
514 if ( posVV0track->Charge() == negVV0track->Charge() ) continue;
515 // avoid ghost TPC tracks
516 if(!(posVV0track->GetStatus() & AliESDtrack::kTPCrefit) ||
517 !(negVV0track->GetStatus() & AliESDtrack::kTPCrefit)) continue;
518 // reject kinks (only necessary on AliESDtracks)
519 if (posVV0track->GetKinkIndex(0)>0 || negVV0track->GetKinkIndex(0)>0) continue;
520 // Get AliExternalTrackParam out of the AliESDtracks
521 posV0track = new AliExternalTrackParam(*posVV0track);
522 negV0track = new AliExternalTrackParam(*negVV0track);
524 // Define the AODv0 from ESDv0 if reading ESDs
525 v0 = TransformESDv0toAODv0(esdV0,twoTrackArrayV0);
527 if( !posV0track || !negV0track ){
528 AliDebug(1,Form(" Couldn't get the V0 daughters"));
532 // fill in the v0 two-external-track-param array
533 twoTrackArrayV0->AddAt(posV0track,0);
534 twoTrackArrayV0->AddAt(negV0track,1);
537 dcaV0 = v0->DcaV0Daughters();
539 // Define the V0 (neutral) track
540 AliNeutralTrackParam *trackV0;
542 const AliVTrack *trackVV0 = dynamic_cast<const AliVTrack*>(v0);
543 if(trackVV0) trackV0 = new AliNeutralTrackParam(trackVV0);
545 Double_t xyz[3], pxpypz[3];
547 esdV0->PxPyPz(pxpypz);
548 Double_t cv[21]; for(int i=0; i<21; i++) cv[i]=0;
549 trackV0 = new AliNeutralTrackParam(xyz,pxpypz,cv,0);
551 // Fill in the object array to create the cascade
552 twoTrackArrayCasc->AddAt(postrack1,0);
553 twoTrackArrayCasc->AddAt(trackV0,1);
555 // Compute the cascade vertex
556 AliAODVertex *vertexCasc = 0;
557 if(fFindVertexForCascades) {
558 // DCA between the two tracks
559 dcaCasc = postrack1->GetDCA(trackV0,fBzkG,xdummy,ydummy);
561 vertexCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
563 // assume Cascade decays at the primary vertex
564 Double_t pos[3],cov[6],chi2perNDF;
566 fV1->GetCovMatrix(cov);
567 chi2perNDF = fV1->GetChi2toNDF();
568 vertexCasc = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,2);
572 delete posV0track; posV0track=NULL;
573 delete negV0track; negV0track=NULL;
574 delete trackV0; trackV0=NULL;
575 if(!fInputAOD) {delete v0; v0=NULL;}
576 twoTrackArrayCasc->Clear();
580 // Create and store the Cascade if passed the cuts
581 ioCascade = MakeCascade(twoTrackArrayCasc,event,vertexCasc,v0,dcaCasc,okCascades);
582 if(okCascades && ioCascade) {
583 AliDebug(1,Form("Storing a cascade object... "));
584 // add the vertex and the cascade to the AOD
585 AliAODVertex *vCasc = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexCasc);
586 rc = new(aodCascadesRef[iCascades++])AliAODRecoCascadeHF(*ioCascade);
587 rc->SetSecondaryVtx(vCasc);
588 vCasc->SetParent(rc);
589 rc->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
590 if(!fInputAOD) vCasc->AddDaughter(v0); // just to fill ref #0 ??
591 AddRefs(vCasc,rc,event,twoTrackArrayCasc); // add the track (proton)
592 vCasc->AddDaughter(v0); // fill the 2prong V0
596 delete posV0track; posV0track=NULL;
597 delete negV0track; negV0track=NULL;
598 delete trackV0; trackV0=NULL;
599 twoTrackArrayV0->Clear();
600 twoTrackArrayCasc->Clear();
601 if(ioCascade) { delete ioCascade; ioCascade=NULL; }
602 if(vertexCasc) { delete vertexCasc; vertexCasc=NULL; }
603 if(!fInputAOD) {delete v0; v0=NULL;}
605 } // end loop on V0's
608 // If there is less than 2 particles continue
610 AliDebug(1,Form(" Not enough tracks: %d",trkEntries));
614 if(postrack1->Charge()<0 && !fLikeSign) continue;
616 // LOOP ON NEGATIVE TRACKS
617 for(iTrkN1=0; iTrkN1<nSeleTrks; iTrkN1++) {
619 if(iTrkN1%1==0) AliDebug(1,Form(" 1st loop on neg: track number %d of %d",iTrkN1,nSeleTrks));
620 //if(iTrkN1%1==0) printf(" 1st loop on neg: track number %d of %d\n",iTrkN1,nSeleTrks);
622 if(iTrkN1==iTrkP1) continue;
624 // get track from tracks array
625 negtrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN1);
627 if(negtrack1->Charge()>0 && !fLikeSign) continue;
629 if(!TESTBIT(seleFlags[iTrkN1],kBitDispl)) continue;
632 if(evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
635 if(postrack1->Charge()==negtrack1->Charge()) { // like-sign
636 isLikeSign2Prong=kTRUE;
637 if(!fLikeSign) continue;
638 if(iTrkN1<iTrkP1) continue; // this is needed to avoid double-counting of like-sign
639 } else { // unlike-sign
640 isLikeSign2Prong=kFALSE;
641 if(postrack1->Charge()<0 || negtrack1->Charge()>0) continue; // this is needed to avoid double-counting of unlike-sign
643 if(evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
648 // back to primary vertex
649 postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
650 negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
652 // DCA between the two tracks
653 dcap1n1 = postrack1->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
654 if(dcap1n1>dcaMax) { negtrack1=0; continue; }
657 twoTrackArray1->AddAt(postrack1,0);
658 twoTrackArray1->AddAt(negtrack1,1);
659 AliAODVertex *vertexp1n1 = ReconstructSecondaryVertex(twoTrackArray1,dispersion);
661 twoTrackArray1->Clear();
667 if(fD0toKpi || fJPSItoEle || fDstar || fLikeSign) {
669 io2Prong = Make2Prong(twoTrackArray1,event,vertexp1n1,dcap1n1,okD0,okJPSI,okD0fromDstar);
671 if((fD0toKpi && okD0) || (fJPSItoEle && okJPSI) || (isLikeSign2Prong && (okD0 || okJPSI))) {
672 // add the vertex and the decay to the AOD
673 AliAODVertex *v2Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
674 if(!isLikeSign2Prong) {
676 rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
677 rd->SetSecondaryVtx(v2Prong);
678 v2Prong->SetParent(rd);
679 AddRefs(v2Prong,rd,event,twoTrackArray1);
682 rd = new(aodJPSItoEleRef[iJPSItoEle++])AliAODRecoDecayHF2Prong(*io2Prong);
683 rd->SetSecondaryVtx(v2Prong);
684 if(!okD0) v2Prong->SetParent(rd); // it cannot have two mothers ...
685 AddRefs(v2Prong,rd,event,twoTrackArray1);
687 } else { // isLikeSign2Prong
688 rd = new(aodLikeSign2ProngRef[iLikeSign2Prong++])AliAODRecoDecayHF2Prong(*io2Prong);
689 rd->SetSecondaryVtx(v2Prong);
690 v2Prong->SetParent(rd);
691 AddRefs(v2Prong,rd,event,twoTrackArray1);
695 if(fDstar && okD0fromDstar && !isLikeSign2Prong) {
696 // write references in io2Prong
698 AddDaughterRefs(vertexp1n1,event,twoTrackArray1);
700 vertexp1n1->AddDaughter(postrack1);
701 vertexp1n1->AddDaughter(negtrack1);
703 io2Prong->SetSecondaryVtx(vertexp1n1);
704 //printf("---> %d %d %d %d %d\n",vertexp1n1->GetNDaughters(),iTrkP1,iTrkN1,postrack1->Charge(),negtrack1->Charge());
705 // create a track from the D0
706 AliNeutralTrackParam *trackD0 = new AliNeutralTrackParam(io2Prong);
708 // LOOP ON TRACKS THAT PASSED THE SOFT PION CUTS
709 for(iTrkSoftPi=0; iTrkSoftPi<nSeleTrks; iTrkSoftPi++) {
711 if(iTrkSoftPi==iTrkP1 || iTrkSoftPi==iTrkN1) continue;
713 if(!TESTBIT(seleFlags[iTrkSoftPi],kBitSoftPi)) continue;
716 if(evtNumber[iTrkP1]==evtNumber[iTrkSoftPi] ||
717 evtNumber[iTrkN1]==evtNumber[iTrkSoftPi] ||
718 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
721 if(iTrkSoftPi%1==0) AliDebug(1,Form(" 1st loop on pi_s: track number %d of %d",iTrkSoftPi,nSeleTrks));
723 trackD0->PropagateToDCA(fV1,fBzkG,kVeryBig);
724 if(trackD0->GetSigmaY2()<0. || trackD0->GetSigmaZ2()<0.) continue; // this is insipired by the AliITStrackV2::Invariant() checks
726 // get track from tracks array
727 trackPi = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkSoftPi);
728 trackPi->PropagateToDCA(fV1,fBzkG,kVeryBig);
730 twoTrackArrayCasc->AddAt(trackPi,0);
731 twoTrackArrayCasc->AddAt(trackD0,1);
733 AliAODVertex *vertexCasc = 0;
735 if(fFindVertexForDstar) {
736 // DCA between the two tracks
737 dcaCasc = trackPi->GetDCA(trackD0,fBzkG,xdummy,ydummy);
739 vertexCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
741 // assume Dstar decays at the primary vertex
742 Double_t pos[3],cov[6],chi2perNDF;
744 fV1->GetCovMatrix(cov);
745 chi2perNDF = fV1->GetChi2toNDF();
746 vertexCasc = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,2);
750 twoTrackArrayCasc->Clear();
755 ioCascade = MakeCascade(twoTrackArrayCasc,event,vertexCasc,io2Prong,dcaCasc,okDstar);
757 // add the D0 to the AOD (if not already done)
759 AliAODVertex *v2Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
760 rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
761 rd->SetSecondaryVtx(v2Prong);
762 v2Prong->SetParent(rd);
763 AddRefs(v2Prong,rd,event,twoTrackArray1);
764 okD0=kTRUE; // this is done to add it only once
766 // add the vertex and the cascade to the AOD
767 AliAODVertex *vCasc = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexCasc);
768 rc = new(aodDstarRef[iDstar++])AliAODRecoCascadeHF(*ioCascade);
769 rc->SetSecondaryVtx(vCasc);
770 vCasc->SetParent(rc);
771 if(!fInputAOD) vCasc->AddDaughter(rd); // just to fill ref #0
772 AddRefs(vCasc,rc,event,twoTrackArrayCasc);
773 vCasc->AddDaughter(rd); // add the D0 (in ref #1)
775 twoTrackArrayCasc->Clear();
777 if(ioCascade) {delete ioCascade; ioCascade=NULL;}
778 delete vertexCasc; vertexCasc=NULL;
779 } // end loop on soft pi tracks
781 if(trackD0) {delete trackD0; trackD0=NULL;}
784 if(io2Prong) {delete io2Prong; io2Prong=NULL;}
787 twoTrackArray1->Clear();
788 if( (!f3Prong && !f4Prong) ||
789 (isLikeSign2Prong && !f3Prong) ) {
796 // 2nd LOOP ON POSITIVE TRACKS
797 for(iTrkP2=iTrkP1+1; iTrkP2<nSeleTrks; iTrkP2++) {
799 if(iTrkP2==iTrkP1 || iTrkP2==iTrkN1) continue;
801 if(iTrkP2%1==0) AliDebug(1,Form(" 2nd loop on pos: track number %d of %d",iTrkP2,nSeleTrks));
803 // get track from tracks array
804 postrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP2);
806 if(postrack2->Charge()<0) continue;
808 if(!TESTBIT(seleFlags[iTrkP2],kBitDispl)) continue;
811 if(evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
812 evtNumber[iTrkN1]==evtNumber[iTrkP2] ||
813 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
816 if(isLikeSign2Prong) { // like-sign pair -> have to build only like-sign triplet
817 if(postrack1->Charge()>0) { // ok: like-sign triplet (+++)
818 isLikeSign3Prong=kTRUE;
822 } else { // normal triplet (+-+)
823 isLikeSign3Prong=kFALSE;
825 if(evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
826 evtNumber[iTrkN1]==evtNumber[iTrkP2] ||
827 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
831 // back to primary vertex
832 postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
833 postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
834 negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
835 //printf("********** %d %d %d\n",postrack1->GetID(),postrack2->GetID(),negtrack1->GetID());
837 dcap2n1 = postrack2->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
838 if(dcap2n1>dcaMax) { postrack2=0; continue; }
839 dcap1p2 = postrack2->GetDCA(postrack1,fBzkG,xdummy,ydummy);
840 if(dcap1p2>dcaMax) { postrack2=0; continue; }
842 // check invariant mass cuts for D+,Ds,Lc
845 if(postrack2->Charge()>0) {
846 threeTrackArray->AddAt(postrack1,0);
847 threeTrackArray->AddAt(negtrack1,1);
848 threeTrackArray->AddAt(postrack2,2);
850 threeTrackArray->AddAt(negtrack1,0);
851 threeTrackArray->AddAt(postrack1,1);
852 threeTrackArray->AddAt(postrack2,2);
854 if(fMassCutBeforeVertexing)
855 massCutOK = SelectInvMass(threeTrackArray);
858 if(f3Prong && !massCutOK) {
859 threeTrackArray->Clear();
867 twoTrackArray2->AddAt(postrack2,0);
868 twoTrackArray2->AddAt(negtrack1,1);
869 AliAODVertex *vertexp2n1 = ReconstructSecondaryVertex(twoTrackArray2,dispersion);
871 twoTrackArray2->Clear();
876 // 3 prong candidates
877 if(f3Prong && massCutOK) {
879 AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
880 io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,vertexp2n1,dcap1n1,dcap2n1,dcap1p2,ok3Prong);
882 AliAODVertex *v3Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
883 if(!isLikeSign3Prong) {
884 rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
885 rd->SetSecondaryVtx(v3Prong);
886 v3Prong->SetParent(rd);
887 AddRefs(v3Prong,rd,event,threeTrackArray);
888 } else { // isLikeSign3Prong
889 rd = new(aodLikeSign3ProngRef[iLikeSign3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
890 rd->SetSecondaryVtx(v3Prong);
891 v3Prong->SetParent(rd);
892 AddRefs(v3Prong,rd,event,threeTrackArray);
895 if(io3Prong) {delete io3Prong; io3Prong=NULL;}
896 if(secVert3PrAOD) {delete secVert3PrAOD; secVert3PrAOD=NULL;}
899 // 4 prong candidates
901 // don't make 4 prong with like-sign pairs and triplets
902 && !isLikeSign2Prong && !isLikeSign3Prong
903 // track-to-track dca cuts already now
904 && dcap1n1 < fCutsD0toKpipipi->GetDCACut()
905 && dcap2n1 < fCutsD0toKpipipi->GetDCACut()) {
907 // back to primary vertex
908 postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
909 postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
910 negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
911 // Vertexing for these 3 (can be taken from above?)
912 threeTrackArray->AddAt(postrack1,0);
913 threeTrackArray->AddAt(negtrack1,1);
914 threeTrackArray->AddAt(postrack2,2);
915 AliAODVertex* vertexp1n1p2 = ReconstructSecondaryVertex(threeTrackArray,dispersion);
917 // 3rd LOOP ON NEGATIVE TRACKS (for 4 prong)
918 for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
920 if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
922 if(iTrkN2%1==0) AliDebug(1,Form(" 3rd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));
924 // get track from tracks array
925 negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
927 if(negtrack2->Charge()>0) continue;
929 if(!TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
931 if(evtNumber[iTrkP1]==evtNumber[iTrkN2] ||
932 evtNumber[iTrkN1]==evtNumber[iTrkN2] ||
933 evtNumber[iTrkP2]==evtNumber[iTrkN2] ||
934 evtNumber[iTrkP1]==evtNumber[iTrkN1] ||
935 evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
936 evtNumber[iTrkN1]==evtNumber[iTrkP2]) continue;
939 // back to primary vertex
940 postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
941 postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
942 negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
943 negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
944 dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
945 if(dcap1n2 > fCutsD0toKpipipi->GetDCACut()) { negtrack2=0; continue; }
946 dcap2n2 = postrack2->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
947 if(dcap2n2 > fCutsD0toKpipipi->GetDCACut()) { negtrack2=0; continue; }
950 fourTrackArray->AddAt(postrack1,0);
951 fourTrackArray->AddAt(negtrack1,1);
952 fourTrackArray->AddAt(postrack2,2);
953 fourTrackArray->AddAt(negtrack2,3);
955 // check invariant mass cuts for D0
957 if(fMassCutBeforeVertexing)
958 massCutOK = SelectInvMass(fourTrackArray);
961 fourTrackArray->Clear();
967 AliAODVertex* secVert4PrAOD = ReconstructSecondaryVertex(fourTrackArray,dispersion);
968 io4Prong = Make4Prong(fourTrackArray,event,secVert4PrAOD,vertexp1n1,vertexp1n1p2,dcap1n1,dcap1n2,dcap2n1,dcap2n2,ok4Prong);
970 AliAODVertex *v4Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert4PrAOD);
971 rd = new(aodCharm4ProngRef[i4Prong++])AliAODRecoDecayHF4Prong(*io4Prong);
972 rd->SetSecondaryVtx(v4Prong);
973 v4Prong->SetParent(rd);
974 AddRefs(v4Prong,rd,event,fourTrackArray);
977 if(io4Prong) {delete io4Prong; io4Prong=NULL;}
978 if(secVert4PrAOD) {delete secVert4PrAOD; secVert4PrAOD=NULL;}
979 fourTrackArray->Clear();
982 } // end loop on negative tracks
984 threeTrackArray->Clear();
992 } // end 2nd loop on positive tracks
994 twoTrackArray2->Clear();
996 // 2nd LOOP ON NEGATIVE TRACKS (for 3 prong -+-)
997 for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
999 if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
1001 if(iTrkN2%1==0) AliDebug(1,Form(" 2nd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));
1003 // get track from tracks array
1004 negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
1006 if(negtrack2->Charge()>0) continue;
1008 if(!TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
1011 if(evtNumber[iTrkP1]==evtNumber[iTrkN2] ||
1012 evtNumber[iTrkN1]==evtNumber[iTrkN2] ||
1013 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
1016 if(isLikeSign2Prong) { // like-sign pair -> have to build only like-sign triplet
1017 if(postrack1->Charge()<0) { // ok: like-sign triplet (---)
1018 isLikeSign3Prong=kTRUE;
1022 } else { // normal triplet (-+-)
1023 isLikeSign3Prong=kFALSE;
1026 // back to primary vertex
1027 postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1028 negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1029 negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1030 //printf("********** %d %d %d\n",postrack1->GetID(),negtrack1->GetID(),negtrack2->GetID());
1032 dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1033 if(dcap1n2>dcaMax) { negtrack2=0; continue; }
1034 dcan1n2 = negtrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1035 if(dcan1n2>dcaMax) { negtrack2=0; continue; }
1037 threeTrackArray->AddAt(negtrack1,0);
1038 threeTrackArray->AddAt(postrack1,1);
1039 threeTrackArray->AddAt(negtrack2,2);
1041 // check invariant mass cuts for D+,Ds,Lc
1043 if(fMassCutBeforeVertexing && f3Prong)
1044 massCutOK = SelectInvMass(threeTrackArray);
1047 threeTrackArray->Clear();
1053 twoTrackArray2->AddAt(postrack1,0);
1054 twoTrackArray2->AddAt(negtrack2,1);
1056 AliAODVertex *vertexp1n2 = ReconstructSecondaryVertex(twoTrackArray2,dispersion);
1058 twoTrackArray2->Clear();
1064 AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1065 io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,vertexp1n2,dcap1n1,dcap1n2,dcan1n2,ok3Prong);
1067 AliAODVertex *v3Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
1068 if(!isLikeSign3Prong) {
1069 rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1070 rd->SetSecondaryVtx(v3Prong);
1071 v3Prong->SetParent(rd);
1072 AddRefs(v3Prong,rd,event,threeTrackArray);
1073 } else { // isLikeSign3Prong
1074 rd = new(aodLikeSign3ProngRef[iLikeSign3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1075 rd->SetSecondaryVtx(v3Prong);
1076 v3Prong->SetParent(rd);
1077 AddRefs(v3Prong,rd,event,threeTrackArray);
1080 if(io3Prong) {delete io3Prong; io3Prong=NULL;}
1081 if(secVert3PrAOD) {delete secVert3PrAOD; secVert3PrAOD=NULL;}
1083 threeTrackArray->Clear();
1087 } // end 2nd loop on negative tracks
1089 twoTrackArray2->Clear();
1093 } // end 1st loop on negative tracks
1096 } // end 1st loop on positive tracks
1099 AliDebug(1,Form(" Total HF vertices in event = %d;",
1100 (Int_t)aodVerticesHFTClArr->GetEntriesFast()));
1102 AliDebug(1,Form(" D0->Kpi in event = %d;",
1103 (Int_t)aodD0toKpiTClArr->GetEntriesFast()));
1106 AliDebug(1,Form(" JPSI->ee in event = %d;",
1107 (Int_t)aodJPSItoEleTClArr->GetEntriesFast()));
1110 AliDebug(1,Form(" Charm->3Prong in event = %d;",
1111 (Int_t)aodCharm3ProngTClArr->GetEntriesFast()));
1114 AliDebug(1,Form(" Charm->4Prong in event = %d;\n",
1115 (Int_t)aodCharm4ProngTClArr->GetEntriesFast()));
1118 AliDebug(1,Form(" D*->D0pi in event = %d;\n",
1119 (Int_t)aodDstarTClArr->GetEntriesFast()));
1122 AliDebug(1,Form(" cascades -> v0 + track in event = %d;\n",
1123 (Int_t)aodCascadesTClArr->GetEntriesFast()));
1126 AliDebug(1,Form(" Like-sign 2Prong in event = %d;\n",
1127 (Int_t)aodLikeSign2ProngTClArr->GetEntriesFast()));
1129 if(fLikeSign && f3Prong) {
1130 AliDebug(1,Form(" Like-sign 3Prong in event = %d;\n",
1131 (Int_t)aodLikeSign3ProngTClArr->GetEntriesFast()));
1135 twoTrackArray1->Delete(); delete twoTrackArray1;
1136 twoTrackArray2->Delete(); delete twoTrackArray2;
1137 twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
1138 twoTrackArrayV0->Delete(); delete twoTrackArrayV0;
1139 threeTrackArray->Clear();
1140 threeTrackArray->Delete(); delete threeTrackArray;
1141 fourTrackArray->Delete(); delete fourTrackArray;
1142 delete [] seleFlags; seleFlags=NULL;
1143 if(evtNumber) {delete [] evtNumber; evtNumber=NULL;}
1146 seleTrksArray.Delete();
1147 if(fAODMap) { delete fAODMap; fAODMap=NULL; }
1152 //----------------------------------------------------------------------------
1153 void AliAnalysisVertexingHF::AddRefs(AliAODVertex *v,AliAODRecoDecayHF *rd,
1154 const AliVEvent *event,
1155 const TObjArray *trkArray) const
1157 // Add the AOD tracks as daughters of the vertex (TRef)
1158 // Also add the references to the primary vertex and to the cuts
1161 AddDaughterRefs(v,event,trkArray);
1162 rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1166 rd->SetListOfCutsRef((TList*)fListOfCuts);
1167 //fListOfCuts->Print();
1168 cout<<fListOfCuts<<endl;
1169 TList *l=(TList*)rd->GetListOfCuts();
1171 if(l) {l->Print(); }else{printf("error\n");}
1176 //----------------------------------------------------------------------------
1177 void AliAnalysisVertexingHF::AddDaughterRefs(AliAODVertex *v,
1178 const AliVEvent *event,
1179 const TObjArray *trkArray) const
1181 // Add the AOD tracks as daughters of the vertex (TRef)
1183 Int_t nDg = v->GetNDaughters();
1185 if(nDg) dg = v->GetDaughter(0);
1187 if(dg) return; // daughters already added
1189 Int_t nTrks = trkArray->GetEntriesFast();
1191 AliExternalTrackParam *track = 0;
1192 AliAODTrack *aodTrack = 0;
1195 for(Int_t i=0; i<nTrks; i++) {
1196 track = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
1197 id = (Int_t)track->GetID();
1198 //printf("---> %d\n",id);
1199 if(id<0) continue; // this track is a AliAODRecoDecay
1200 aodTrack = (AliAODTrack*)event->GetTrack(fAODMap[id]);
1201 v->AddDaughter(aodTrack);
1206 //---------------------------------------------------------------------------
1207 void AliAnalysisVertexingHF::FixReferences(AliAODEvent *aod)
1209 // Checks that the references to the daughter tracks are properly
1210 // assigned and reassigns them if needed
1214 TClonesArray *inputArray=(TClonesArray*)aod->GetList()->FindObject("VerticesHF");
1215 if(!inputArray) return;
1217 AliAODTrack *track = 0;
1218 AliAODVertex *vertex = 0;
1220 Bool_t needtofix=kFALSE;
1221 for(Int_t iv=0; iv<inputArray->GetEntriesFast(); iv++) {
1222 vertex = (AliAODVertex*)inputArray->UncheckedAt(iv);
1223 for(Int_t id=0; id<vertex->GetNDaughters(); id++) {
1224 track = (AliAODTrack*)vertex->GetDaughter(id);
1225 if(!track->GetStatus()) needtofix=kTRUE;
1227 if(needtofix) break;
1230 if(!needtofix) return;
1233 printf("Fixing references\n");
1235 fAODMapSize = 100000;
1236 fAODMap = new Int_t[fAODMapSize];
1238 for(Int_t i=0; i<aod->GetNumberOfTracks(); i++) {
1239 track = aod->GetTrack(i);
1241 // skip pure ITS SA tracks
1242 if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
1244 // skip tracks without ITS
1245 if(!(track->GetStatus()&AliESDtrack::kITSin)) continue;
1247 // TEMPORARY: check that the cov matrix is there
1248 Double_t covtest[21];
1249 if(!track->GetCovarianceXYZPxPyPz(covtest)) continue;
1252 fAODMap[(Int_t)track->GetID()] = i;
1256 Int_t ids[4]={-1,-1,-1,-1};
1257 for(Int_t iv=0; iv<inputArray->GetEntriesFast(); iv++) {
1258 Bool_t cascade=kFALSE;
1259 vertex = (AliAODVertex*)inputArray->UncheckedAt(iv);
1261 Int_t nDgs = vertex->GetNDaughters();
1262 for(id=0; id<nDgs; id++) {
1263 track = (AliAODTrack*)vertex->GetDaughter(id);
1264 if(track->Charge()==0) {cascade=kTRUE; continue;} // cascade
1265 ids[id]=(Int_t)track->GetID();
1266 vertex->RemoveDaughter(track);
1268 if(cascade) continue;
1269 for(id=0; id<nDgs; id++) {
1270 track = aod->GetTrack(fAODMap[ids[id]]);
1271 vertex->AddDaughter(track);
1278 //----------------------------------------------------------------------------
1279 AliAODRecoCascadeHF* AliAnalysisVertexingHF::MakeCascade(
1280 TObjArray *twoTrackArray,AliVEvent *event,
1281 AliAODVertex *secVert,
1282 AliAODRecoDecayHF2Prong *rd2Prong,
1284 Bool_t &okDstar) const
1286 // Make the cascade as a 2Prong decay and check if it passes Dstar
1287 // reconstruction cuts
1291 Bool_t dummy1,dummy2,dummy3;
1293 // We use Make2Prong to construct the AliAODRecoCascadeHF
1294 // (which inherits from AliAODRecoDecayHF2Prong)
1295 AliAODRecoCascadeHF *theCascade =
1296 (AliAODRecoCascadeHF*)Make2Prong(twoTrackArray,event,secVert,dca,
1297 dummy1,dummy2,dummy3);
1298 if(!theCascade) return 0x0;
1301 AliESDtrack *trackPi = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
1302 theCascade->SetCharge(trackPi->Charge());
1304 //--- selection cuts
1306 AliAODRecoCascadeHF *tmpCascade = new AliAODRecoCascadeHF(*theCascade);
1307 tmpCascade->GetSecondaryVtx()->AddDaughter(trackPi);
1308 tmpCascade->GetSecondaryVtx()->AddDaughter(rd2Prong);
1309 AliAODVertex *primVertexAOD=0;
1310 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
1311 // take event primary vertex
1312 primVertexAOD = PrimaryVertex();
1313 tmpCascade->SetOwnPrimaryVtx(primVertexAOD);
1314 rd2Prong->SetOwnPrimaryVtx(primVertexAOD);
1318 okDstar = (Bool_t)fCutsDStartoKpipi->IsSelected(tmpCascade,AliRDHFCuts::kCandidate);
1320 tmpCascade->GetSecondaryVtx()->RemoveDaughters();
1321 tmpCascade->UnsetOwnPrimaryVtx();
1322 delete tmpCascade; tmpCascade=NULL;
1323 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1324 rd2Prong->UnsetOwnPrimaryVtx();
1326 if(primVertexAOD) {delete primVertexAOD; primVertexAOD=NULL;}
1333 //----------------------------------------------------------------------------
1334 AliAODRecoCascadeHF* AliAnalysisVertexingHF::MakeCascade(
1335 TObjArray *twoTrackArray,AliVEvent *event,
1336 AliAODVertex *secVert,
1339 Bool_t &okCascades) const
1342 // Make the cascade as a 2Prong decay and check if it passes
1343 // cascades reconstruction cuts
1345 // AliDebug(2,Form(" building the cascade"));
1347 Bool_t dummy1,dummy2,dummy3;
1349 // We use Make2Prong to construct the AliAODRecoCascadeHF
1350 // (which inherits from AliAODRecoDecayHF2Prong)
1351 AliAODRecoCascadeHF *theCascade =
1352 (AliAODRecoCascadeHF*)Make2Prong(twoTrackArray,event,secVert,dca,
1353 dummy1,dummy2,dummy3);
1354 if(!theCascade) return 0x0;
1356 // bachelor track and charge
1357 AliESDtrack *trackBachelor = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
1358 theCascade->SetCharge(trackBachelor->Charge());
1360 //--- selection cuts
1362 AliAODRecoCascadeHF *tmpCascade = new AliAODRecoCascadeHF(*theCascade);
1363 tmpCascade->GetSecondaryVtx()->AddDaughter(trackBachelor);
1364 tmpCascade->GetSecondaryVtx()->AddDaughter(v0);
1365 AliAODVertex *primVertexAOD=0;
1366 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
1367 // take event primary vertex
1368 primVertexAOD = PrimaryVertex();
1369 if(!primVertexAOD) primVertexAOD = (AliAODVertex*)event->GetPrimaryVertex();
1370 tmpCascade->SetOwnPrimaryVtx(primVertexAOD);
1374 Bool_t okLcksp=0, okLcLpi=0;
1375 if(fCascades && fInputAOD){
1376 okCascades = (Bool_t)fCutsLctoV0->IsSelected(tmpCascade,AliRDHFCuts::kCandidate);
1377 if(okCascades==1) okLcksp=1;
1378 if(okCascades==2) okLcLpi=1;
1379 if(okCascades==3) { okLcksp=1; okLcLpi=1;}
1381 else { AliDebug(2,Form("The cascade is contructed from ESDs, no cuts are applied")); okCascades=kTRUE; }// no cuts implemented from ESDs
1382 tmpCascade->GetSecondaryVtx()->RemoveDaughters();
1383 tmpCascade->UnsetOwnPrimaryVtx();
1384 delete tmpCascade; tmpCascade=NULL;
1385 if(primVertexAOD) {delete primVertexAOD; primVertexAOD=NULL;}
1391 //-----------------------------------------------------------------------------
1392 AliAODRecoDecayHF2Prong *AliAnalysisVertexingHF::Make2Prong(
1393 TObjArray *twoTrackArray,AliVEvent *event,
1394 AliAODVertex *secVert,Double_t dca,
1395 Bool_t &okD0,Bool_t &okJPSI,
1396 Bool_t &okD0fromDstar) const
1398 // Make 2Prong candidates and check if they pass D0toKpi or BtoJPSI
1399 // reconstruction cuts
1400 // G.E.Bruno (J/psi), A.Dainese (D0->Kpi)
1402 okD0=kFALSE; okJPSI=kFALSE; okD0fromDstar=kFALSE;
1404 Double_t px[2],py[2],pz[2],d0[2],d0err[2];
1405 AliESDtrack *postrack = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
1406 AliESDtrack *negtrack = (AliESDtrack*)twoTrackArray->UncheckedAt(1);
1408 // propagate tracks to secondary vertex, to compute inv. mass
1409 postrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
1410 negtrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
1412 Double_t momentum[3];
1413 postrack->GetPxPyPz(momentum);
1414 px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
1415 negtrack->GetPxPyPz(momentum);
1416 px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
1419 // invariant mass cut (try to improve coding here..)
1420 Bool_t okMassCut=kFALSE;
1421 if(!okMassCut && fD0toKpi) if(SelectInvMass(0,2,px,py,pz)) okMassCut=kTRUE;
1422 if(!okMassCut && fJPSItoEle) if(SelectInvMass(1,2,px,py,pz)) okMassCut=kTRUE;
1423 if(!okMassCut && fDstar) if(SelectInvMass(3,2,px,py,pz)) okMassCut=kTRUE;
1425 AliDebug(2," candidate didn't pass mass cut");
1428 // primary vertex to be used by this candidate
1429 AliAODVertex *primVertexAOD = PrimaryVertex(twoTrackArray,event);
1430 if(!primVertexAOD) return 0x0;
1433 Double_t d0z0[2],covd0z0[3];
1434 postrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1436 d0err[0] = TMath::Sqrt(covd0z0[0]);
1437 negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1439 d0err[1] = TMath::Sqrt(covd0z0[0]);
1441 // create the object AliAODRecoDecayHF2Prong
1442 AliAODRecoDecayHF2Prong *the2Prong = new AliAODRecoDecayHF2Prong(secVert,px,py,pz,d0,d0err,dca);
1443 the2Prong->SetOwnPrimaryVtx(primVertexAOD);
1444 UShort_t id[2]={(UShort_t)postrack->GetID(),(UShort_t)negtrack->GetID()};
1445 the2Prong->SetProngIDs(2,id);
1446 delete primVertexAOD; primVertexAOD=NULL;
1449 if(postrack->Charge()!=0 && negtrack->Charge()!=0) { // don't apply these cuts if it's a Dstar
1451 if(fD0toKpi) okD0 = (Bool_t)fCutsD0toKpi->IsSelected(the2Prong,AliRDHFCuts::kCandidate);
1452 //if(fDebug && fD0toKpi) printf(" %d\n",(Int_t)okD0);
1453 // select J/psi from B
1454 if(fJPSItoEle) okJPSI = (Bool_t)fCutsJpsitoee->IsSelected(the2Prong,AliRDHFCuts::kCandidate);
1455 //if(fDebug && fJPSItoEle) printf(" %d\n",(Int_t)okJPSI);
1456 // select D0->Kpi from Dstar
1457 if(fDstar) okD0fromDstar = (Bool_t)fCutsDStartoKpipi->IsD0FromDStarSelected(the2Prong->Pt(),the2Prong,AliRDHFCuts::kCandidate);
1458 //if(fDebug && fDstar) printf(" %d\n",(Int_t)okD0fromDstar);
1462 // remove the primary vertex (was used only for selection)
1463 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1464 the2Prong->UnsetOwnPrimaryVtx();
1467 // get PID info from ESD
1468 Double_t esdpid0[5]={0.,0.,0.,0.,0.};
1469 if(postrack->GetStatus()&AliESDtrack::kESDpid) postrack->GetESDpid(esdpid0);
1470 Double_t esdpid1[5]={0.,0.,0.,0.,0.};
1471 if(negtrack->GetStatus()&AliESDtrack::kESDpid) negtrack->GetESDpid(esdpid1);
1472 Double_t esdpid[10];
1473 for(Int_t i=0;i<5;i++) {
1474 esdpid[i] = esdpid0[i];
1475 esdpid[5+i] = esdpid1[i];
1477 the2Prong->SetPID(2,esdpid);
1481 //----------------------------------------------------------------------------
1482 AliAODRecoDecayHF3Prong* AliAnalysisVertexingHF::Make3Prong(
1483 TObjArray *threeTrackArray,AliVEvent *event,
1484 AliAODVertex *secVert,Double_t dispersion,
1485 const AliAODVertex *vertexp1n1,const AliAODVertex *vertexp2n1,
1486 Double_t dcap1n1,Double_t dcap2n1,Double_t dcap1p2,
1487 Bool_t &ok3Prong) const
1489 // Make 3Prong candidates and check if they pass Dplus or Ds or Lambdac
1490 // reconstruction cuts
1495 if(!secVert || !vertexp1n1 || !vertexp2n1) return 0x0;
1497 Double_t px[3],py[3],pz[3],d0[3],d0err[3];
1498 Double_t momentum[3];
1501 AliESDtrack *postrack1 = (AliESDtrack*)threeTrackArray->UncheckedAt(0);
1502 AliESDtrack *negtrack = (AliESDtrack*)threeTrackArray->UncheckedAt(1);
1503 AliESDtrack *postrack2 = (AliESDtrack*)threeTrackArray->UncheckedAt(2);
1505 postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
1506 negtrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
1507 postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
1508 postrack1->GetPxPyPz(momentum);
1509 px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
1510 negtrack->GetPxPyPz(momentum);
1511 px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
1512 postrack2->GetPxPyPz(momentum);
1513 px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2];
1515 // invariant mass cut for D+, Ds, Lc
1516 Bool_t okMassCut=kFALSE;
1517 if(fMassCutBeforeVertexing) okMassCut=kTRUE; // mass cut already done and passed
1518 if(!okMassCut && f3Prong) if(SelectInvMass(2,3,px,py,pz)) okMassCut=kTRUE;
1520 AliDebug(2," candidate didn't pass mass cut");
1524 // primary vertex to be used by this candidate
1525 AliAODVertex *primVertexAOD = PrimaryVertex(threeTrackArray,event);
1526 if(!primVertexAOD) return 0x0;
1528 Double_t d0z0[2],covd0z0[3];
1529 postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1531 d0err[0] = TMath::Sqrt(covd0z0[0]);
1532 negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1534 d0err[1] = TMath::Sqrt(covd0z0[0]);
1535 postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1537 d0err[2] = TMath::Sqrt(covd0z0[0]);
1540 // create the object AliAODRecoDecayHF3Prong
1541 Double_t pos[3]; primVertexAOD->GetXYZ(pos);
1542 Double_t dca[3]={dcap1n1,dcap2n1,dcap1p2};
1543 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]));
1544 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]));
1545 Short_t charge=(Short_t)(postrack1->Charge()+postrack2->Charge()+negtrack->Charge());
1546 AliAODRecoDecayHF3Prong *the3Prong = new AliAODRecoDecayHF3Prong(secVert,px,py,pz,d0,d0err,dca,dispersion,dist12,dist23,charge);
1547 the3Prong->SetOwnPrimaryVtx(primVertexAOD);
1548 UShort_t id[3]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack->GetID(),(UShort_t)postrack2->GetID()};
1549 the3Prong->SetProngIDs(3,id);
1551 delete primVertexAOD; primVertexAOD=NULL;
1553 // select D+->Kpipi, Ds->KKpi, Lc->pKpi
1557 if(fCutsDplustoKpipi->IsSelected(the3Prong,AliRDHFCuts::kCandidate)) ok3Prong = kTRUE;
1558 if(fCutsDstoKKpi->IsSelected(the3Prong,AliRDHFCuts::kCandidate)) ok3Prong = kTRUE;
1559 if(fCutsLctopKpi->IsSelected(the3Prong,AliRDHFCuts::kCandidate)) ok3Prong = kTRUE;
1562 //if(fDebug) printf("ok3Prong: %d\n",(Int_t)ok3Prong);
1564 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1565 the3Prong->UnsetOwnPrimaryVtx();
1568 // get PID info from ESD
1569 Double_t esdpid0[5]={0.,0.,0.,0.,0.};
1570 if(postrack1->GetStatus()&AliESDtrack::kESDpid) postrack1->GetESDpid(esdpid0);
1571 Double_t esdpid1[5]={0.,0.,0.,0.,0.};
1572 if(negtrack->GetStatus()&AliESDtrack::kESDpid) negtrack->GetESDpid(esdpid1);
1573 Double_t esdpid2[5]={0.,0.,0.,0.,0.};
1574 if(postrack2->GetStatus()&AliESDtrack::kESDpid) postrack2->GetESDpid(esdpid2);
1576 Double_t esdpid[15];
1577 for(Int_t i=0;i<5;i++) {
1578 esdpid[i] = esdpid0[i];
1579 esdpid[5+i] = esdpid1[i];
1580 esdpid[10+i] = esdpid2[i];
1582 the3Prong->SetPID(3,esdpid);
1586 //----------------------------------------------------------------------------
1587 AliAODRecoDecayHF4Prong* AliAnalysisVertexingHF::Make4Prong(
1588 TObjArray *fourTrackArray,AliVEvent *event,
1589 AliAODVertex *secVert,
1590 const AliAODVertex *vertexp1n1,
1591 const AliAODVertex *vertexp1n1p2,
1592 Double_t dcap1n1,Double_t dcap1n2,
1593 Double_t dcap2n1,Double_t dcap2n2,
1594 Bool_t &ok4Prong) const
1596 // Make 4Prong candidates and check if they pass D0toKpipipi
1597 // reconstruction cuts
1598 // G.E.Bruno, R.Romita
1601 if(!secVert || !vertexp1n1 || !vertexp1n1p2) return 0x0;
1603 Double_t px[4],py[4],pz[4],d0[4],d0err[4];//d0z[3];
1605 AliESDtrack *postrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(0);
1606 AliESDtrack *negtrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(1);
1607 AliESDtrack *postrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(2);
1608 AliESDtrack *negtrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(3);
1610 postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
1611 negtrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
1612 postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
1613 negtrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
1615 Double_t momentum[3];
1616 postrack1->GetPxPyPz(momentum);
1617 px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
1618 negtrack1->GetPxPyPz(momentum);
1619 px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
1620 postrack2->GetPxPyPz(momentum);
1621 px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2];
1622 negtrack2->GetPxPyPz(momentum);
1623 px[3] = momentum[0]; py[3] = momentum[1]; pz[3] = momentum[2];
1625 // invariant mass cut for rho or D0 (try to improve coding here..)
1626 Bool_t okMassCut=kFALSE;
1627 if(fMassCutBeforeVertexing) okMassCut=kTRUE; // mass cut already done and passed
1628 if(!okMassCut && !(fCutsD0toKpipipi->GetUsePID())) { //no PID, to be implemented with PID
1629 if(SelectInvMass(4,4,px,py,pz)) okMassCut=kTRUE;
1632 //if(fDebug) printf(" candidate didn't pass mass cut\n");
1633 //printf(" candidate didn't pass mass cut\n");
1637 // primary vertex to be used by this candidate
1638 AliAODVertex *primVertexAOD = PrimaryVertex(fourTrackArray,event);
1639 if(!primVertexAOD) return 0x0;
1641 Double_t d0z0[2],covd0z0[3];
1642 postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1644 d0err[0] = TMath::Sqrt(covd0z0[0]);
1645 negtrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1647 d0err[1] = TMath::Sqrt(covd0z0[0]);
1648 postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1650 d0err[2] = TMath::Sqrt(covd0z0[0]);
1651 negtrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1653 d0err[3] = TMath::Sqrt(covd0z0[0]);
1656 // create the object AliAODRecoDecayHF4Prong
1657 Double_t pos[3]; primVertexAOD->GetXYZ(pos);
1658 Double_t dca[6]={dcap1n1,0.,dcap1n2,dcap2n1,0.,dcap2n2};
1659 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]));
1660 Double_t dist3=TMath::Sqrt((vertexp1n1p2->GetX()-pos[0])*(vertexp1n1p2->GetX()-pos[0])+(vertexp1n1p2->GetY()-pos[1])*(vertexp1n1p2->GetY()-pos[1])+(vertexp1n1p2->GetZ()-pos[2])*(vertexp1n1p2->GetZ()-pos[2]));
1661 Double_t dist4=TMath::Sqrt((secVert->GetX()-pos[0])*(secVert->GetX()-pos[0])+(secVert->GetY()-pos[1])*(secVert->GetY()-pos[1])+(secVert->GetZ()-pos[2])*(secVert->GetZ()-pos[2]));
1663 AliAODRecoDecayHF4Prong *the4Prong = new AliAODRecoDecayHF4Prong(secVert,px,py,pz,d0,d0err,dca,dist12,dist3,dist4,charge);
1664 the4Prong->SetOwnPrimaryVtx(primVertexAOD);
1665 UShort_t id[4]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack1->GetID(),(UShort_t)postrack2->GetID(),(UShort_t)negtrack2->GetID()};
1666 the4Prong->SetProngIDs(4,id);
1668 delete primVertexAOD; primVertexAOD=NULL;
1670 ok4Prong=(Bool_t)fCutsD0toKpipipi->IsSelected(the4Prong,AliRDHFCuts::kCandidate);
1673 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1674 the4Prong->UnsetOwnPrimaryVtx();
1678 // get PID info from ESD
1679 Double_t esdpid0[5]={0.,0.,0.,0.,0.};
1680 if(postrack1->GetStatus()&AliESDtrack::kESDpid) postrack1->GetESDpid(esdpid0);
1681 Double_t esdpid1[5]={0.,0.,0.,0.,0.};
1682 if(negtrack1->GetStatus()&AliESDtrack::kESDpid) negtrack1->GetESDpid(esdpid1);
1683 Double_t esdpid2[5]={0.,0.,0.,0.,0.};
1684 if(postrack2->GetStatus()&AliESDtrack::kESDpid) postrack2->GetESDpid(esdpid2);
1685 Double_t esdpid3[5]={0.,0.,0.,0.,0.};
1686 if(negtrack2->GetStatus()&AliESDtrack::kESDpid) negtrack2->GetESDpid(esdpid3);
1688 Double_t esdpid[20];
1689 for(Int_t i=0;i<5;i++) {
1690 esdpid[i] = esdpid0[i];
1691 esdpid[5+i] = esdpid1[i];
1692 esdpid[10+i] = esdpid2[i];
1693 esdpid[15+i] = esdpid3[i];
1695 the4Prong->SetPID(4,esdpid);
1699 //-----------------------------------------------------------------------------
1700 AliAODVertex* AliAnalysisVertexingHF::PrimaryVertex(const TObjArray *trkArray,
1701 AliVEvent *event) const
1703 // Returns primary vertex to be used for this candidate
1705 AliESDVertex *vertexESD = 0;
1706 AliAODVertex *vertexAOD = 0;
1709 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
1710 // primary vertex from the input event
1712 vertexESD = new AliESDVertex(*fV1);
1715 // primary vertex specific to this candidate
1717 Int_t nTrks = trkArray->GetEntriesFast();
1718 AliVertexerTracks *vertexer = new AliVertexerTracks(event->GetMagneticField());
1720 if(fRecoPrimVtxSkippingTrks) {
1721 // recalculating the vertex
1723 if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraint")) {
1724 Float_t diamondcovxy[3];
1725 event->GetDiamondCovXY(diamondcovxy);
1726 Double_t pos[3]={event->GetDiamondX(),event->GetDiamondY(),0.};
1727 Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.*10.};
1728 AliESDVertex *diamond = new AliESDVertex(pos,cov,1.,1);
1729 vertexer->SetVtxStart(diamond);
1730 delete diamond; diamond=NULL;
1731 if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraintOnlyFitter"))
1732 vertexer->SetOnlyFitter();
1734 Int_t skipped[1000];
1735 Int_t nTrksToSkip=0,id;
1736 AliExternalTrackParam *t = 0;
1737 for(Int_t i=0; i<nTrks; i++) {
1738 t = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
1739 id = (Int_t)t->GetID();
1741 skipped[nTrksToSkip++] = id;
1744 // For AOD, skip also tracks without covariance matrix
1746 Double_t covtest[21];
1747 for(Int_t j=0; j<event->GetNumberOfTracks(); j++) {
1748 AliVTrack *vtrack = (AliVTrack*)event->GetTrack(j);
1749 if(!vtrack->GetCovarianceXYZPxPyPz(covtest)) {
1750 id = (Int_t)vtrack->GetID();
1752 skipped[nTrksToSkip++] = id;
1757 vertexer->SetSkipTracks(nTrksToSkip,skipped);
1758 vertexESD = (AliESDVertex*)vertexer->FindPrimaryVertex(event);
1760 } else if(fRmTrksFromPrimVtx) {
1761 // removing the prongs tracks
1763 TObjArray rmArray(nTrks);
1764 UShort_t *rmId = new UShort_t[nTrks];
1765 AliESDtrack *esdTrack = 0;
1767 for(Int_t i=0; i<nTrks; i++) {
1768 t = (AliESDtrack*)trkArray->UncheckedAt(i);
1769 esdTrack = new AliESDtrack(*t);
1770 rmArray.AddLast(esdTrack);
1771 if(esdTrack->GetID()>=0) {
1772 rmId[i]=(UShort_t)esdTrack->GetID();
1777 Float_t diamondxy[2]={event->GetDiamondX(),event->GetDiamondY()};
1778 vertexESD = vertexer->RemoveTracksFromVertex(fV1,&rmArray,rmId,diamondxy);
1779 delete [] rmId; rmId=NULL;
1784 if(!vertexESD) return vertexAOD;
1785 if(vertexESD->GetNContributors()<=0) {
1786 AliDebug(2,"vertexing failed");
1787 delete vertexESD; vertexESD=NULL;
1791 delete vertexer; vertexer=NULL;
1795 // convert to AliAODVertex
1796 Double_t pos[3],cov[6],chi2perNDF;
1797 vertexESD->GetXYZ(pos); // position
1798 vertexESD->GetCovMatrix(cov); //covariance matrix
1799 chi2perNDF = vertexESD->GetChi2toNDF();
1800 delete vertexESD; vertexESD=NULL;
1802 vertexAOD = new AliAODVertex(pos,cov,chi2perNDF);
1806 //-----------------------------------------------------------------------------
1807 void AliAnalysisVertexingHF::PrintStatus() const {
1808 // Print parameters being used
1810 //printf("Preselections:\n");
1811 // fTrackFilter->Dump();
1813 printf("Secondary vertex with Kalman filter package (AliKFParticle)\n");
1815 printf("Secondary vertex with AliVertexerTracks\n");
1817 if(fRecoPrimVtxSkippingTrks) printf("RecoPrimVtxSkippingTrks\n");
1818 if(fRmTrksFromPrimVtx) printf("RmTrksFromPrimVtx\n");
1820 printf("Reconstruct D0->Kpi candidates with cuts:\n");
1821 if(fCutsD0toKpi) fCutsD0toKpi->PrintAll();
1824 printf("Reconstruct D*->D0pi candidates with cuts:\n");
1825 if(fFindVertexForDstar) {
1826 printf(" Reconstruct a secondary vertex for the D*\n");
1828 printf(" Assume the D* comes from the primary vertex\n");
1830 if(fCutsDStartoKpipi) fCutsDStartoKpipi->PrintAll();
1833 printf("Reconstruct J/psi from B candidates with cuts:\n");
1834 if(fCutsJpsitoee) fCutsJpsitoee->PrintAll();
1837 printf("Reconstruct 3 prong candidates.\n");
1838 printf(" D+->Kpipi cuts:\n");
1839 if(fCutsDplustoKpipi) fCutsDplustoKpipi->PrintAll();
1840 printf(" Ds->KKpi cuts:\n");
1841 if(fCutsDstoKKpi) fCutsDstoKKpi->PrintAll();
1842 printf(" Lc->pKpi cuts:\n");
1843 if(fCutsLctopKpi) fCutsLctopKpi->PrintAll();
1846 printf("Reconstruct 4 prong candidates.\n");
1847 printf(" D0->Kpipipi cuts:\n");
1848 if(fCutsD0toKpipipi) fCutsD0toKpipipi->PrintAll();
1851 printf("Reconstruct cascades candidates formed with v0s.\n");
1852 printf(" Lc -> k0s P & Lc -> L Pi cuts:\n");
1853 if(fCutsLctoV0) fCutsLctoV0->PrintAll();
1858 //-----------------------------------------------------------------------------
1859 AliAODVertex* AliAnalysisVertexingHF::ReconstructSecondaryVertex(TObjArray *trkArray,
1860 Double_t &dispersion,Bool_t useTRefArray) const
1862 // Secondary vertex reconstruction with AliVertexerTracks or AliKFParticle
1864 AliESDVertex *vertexESD = 0;
1865 AliAODVertex *vertexAOD = 0;
1867 if(!fSecVtxWithKF) { // AliVertexerTracks
1869 AliVertexerTracks *vertexer = new AliVertexerTracks(fBzkG);
1870 vertexer->SetVtxStart(fV1);
1871 vertexESD = (AliESDVertex*)vertexer->VertexForSelectedESDTracks(trkArray);
1872 delete vertexer; vertexer=NULL;
1874 if(!vertexESD) return vertexAOD;
1876 if(vertexESD->GetNContributors()!=trkArray->GetEntriesFast()) {
1877 AliDebug(2,"vertexing failed");
1878 delete vertexESD; vertexESD=NULL;
1882 } else { // Kalman Filter vertexer (AliKFParticle)
1884 AliKFParticle::SetField(fBzkG);
1886 AliKFVertex vertexKF;
1888 Int_t nTrks = trkArray->GetEntriesFast();
1889 for(Int_t i=0; i<nTrks; i++) {
1890 AliESDtrack *esdTrack = (AliESDtrack*)trkArray->At(i);
1891 AliKFParticle daughterKF(*esdTrack,211);
1892 vertexKF.AddDaughter(daughterKF);
1894 vertexESD = new AliESDVertex(vertexKF.Parameters(),
1895 vertexKF.CovarianceMatrix(),
1897 vertexKF.GetNContributors());
1901 // convert to AliAODVertex
1902 Double_t pos[3],cov[6],chi2perNDF;
1903 vertexESD->GetXYZ(pos); // position
1904 vertexESD->GetCovMatrix(cov); //covariance matrix
1905 chi2perNDF = vertexESD->GetChi2toNDF();
1906 dispersion = vertexESD->GetDispersion();
1907 delete vertexESD; vertexESD=NULL;
1909 Int_t nprongs= (useTRefArray ? 0 : trkArray->GetEntriesFast());
1910 vertexAOD = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,nprongs);
1914 //-----------------------------------------------------------------------------
1915 Bool_t AliAnalysisVertexingHF::SelectInvMass(TObjArray *trkArray) const {
1916 // Invariant mass cut on tracks
1918 Int_t nProngs=trkArray->GetEntriesFast();
1919 Int_t retval=kFALSE;
1921 Double_t momentum[3];
1922 Double_t px3[3],py3[3],pz3[3];
1923 Double_t px4[4],py4[4],pz4[4];
1924 AliESDtrack *postrack1=0;
1925 AliESDtrack *postrack2=0;
1926 AliESDtrack *negtrack1=0;
1927 AliESDtrack *negtrack2=0;
1931 // invariant mass cut for D+, Ds, Lc
1932 postrack1 = (AliESDtrack*)trkArray->UncheckedAt(0);
1933 negtrack1 = (AliESDtrack*)trkArray->UncheckedAt(1);
1934 postrack2 = (AliESDtrack*)trkArray->UncheckedAt(2);
1935 postrack1->GetPxPyPz(momentum);
1936 px3[0] = momentum[0]; py3[0] = momentum[1]; pz3[0] = momentum[2];
1937 negtrack1->GetPxPyPz(momentum);
1938 px3[1] = momentum[0]; py3[1] = momentum[1]; pz3[1] = momentum[2];
1939 postrack2->GetPxPyPz(momentum);
1940 px3[2] = momentum[0]; py3[2] = momentum[1]; pz3[2] = momentum[2];
1941 retval = SelectInvMass(2,3,px3,py3,pz3);
1944 // invariant mass cut for D0->4prong
1945 postrack1 = (AliESDtrack*)trkArray->UncheckedAt(0);
1946 negtrack1 = (AliESDtrack*)trkArray->UncheckedAt(1);
1947 postrack2 = (AliESDtrack*)trkArray->UncheckedAt(2);
1948 negtrack2 = (AliESDtrack*)trkArray->UncheckedAt(3);
1949 postrack1->GetPxPyPz(momentum);
1950 px4[0] = momentum[0]; py4[0] = momentum[1]; pz4[0] = momentum[2];
1951 negtrack1->GetPxPyPz(momentum);
1952 px4[1] = momentum[0]; py4[1] = momentum[1]; pz4[1] = momentum[2];
1953 postrack2->GetPxPyPz(momentum);
1954 px4[2] = momentum[0]; py4[2] = momentum[1]; pz4[2] = momentum[2];
1955 negtrack2->GetPxPyPz(momentum);
1956 px4[3] = momentum[0]; py4[3] = momentum[1]; pz4[3] = momentum[2];
1957 retval = SelectInvMass(4,4,px4,py4,pz4);
1960 printf("SelectInvMass(): wrong decay selection\n");
1966 //-----------------------------------------------------------------------------
1967 Bool_t AliAnalysisVertexingHF::SelectInvMass(Int_t decay,
1971 Double_t *pz) const {
1972 // Check invariant mass cut
1974 UInt_t pdg2[2],pdg3[3],pdg4[4];
1977 Bool_t retval=kFALSE;
1981 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
1982 pdg2[0]=211; pdg2[1]=321;
1983 mPDG=TDatabasePDG::Instance()->GetParticle(421)->Mass();
1984 minv = fMassCalc2->InvMass(nprongs,pdg2);
1985 if(TMath::Abs(minv-mPDG)<fCutsD0toKpi->GetMassCut()) retval=kTRUE;
1986 pdg2[0]=321; pdg2[1]=211;
1987 minv = fMassCalc2->InvMass(nprongs,pdg2);
1988 if(TMath::Abs(minv-mPDG)<fCutsD0toKpi->GetMassCut()) retval=kTRUE;
1991 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
1992 pdg2[0]=11; pdg2[1]=11;
1993 mPDG=TDatabasePDG::Instance()->GetParticle(443)->Mass();
1994 minv = fMassCalc2->InvMass(nprongs,pdg2);
1995 if(TMath::Abs(minv-mPDG)<fCutsJpsitoee->GetMassCut()) retval=kTRUE;
1997 case 2: // D+->Kpipi
1998 fMassCalc3->SetPxPyPzProngs(nprongs,px,py,pz);
1999 pdg3[0]=211; pdg3[1]=321; pdg3[2]=211;
2000 mPDG=TDatabasePDG::Instance()->GetParticle(411)->Mass();
2001 minv = fMassCalc3->InvMass(nprongs,pdg3);
2002 if(TMath::Abs(minv-mPDG)<fCutsDplustoKpipi->GetMassCut()) retval=kTRUE;
2004 pdg3[0]=321; pdg3[1]=321; pdg3[2]=211;
2005 mPDG=TDatabasePDG::Instance()->GetParticle(431)->Mass();
2006 minv = fMassCalc3->InvMass(nprongs,pdg3);
2007 if(TMath::Abs(minv-mPDG)<fCutsDstoKKpi->GetMassCut()) retval=kTRUE;
2008 pdg3[0]=211; pdg3[1]=321; pdg3[2]=321;
2009 minv = fMassCalc3->InvMass(nprongs,pdg3);
2010 if(TMath::Abs(minv-mPDG)<fCutsDstoKKpi->GetMassCut()) retval=kTRUE;
2012 pdg3[0]=2212; pdg3[1]=321; pdg3[2]=211;
2013 mPDG=TDatabasePDG::Instance()->GetParticle(4122)->Mass();
2014 minv = fMassCalc3->InvMass(nprongs,pdg3);
2015 if(TMath::Abs(minv-mPDG)<fCutsLctopKpi->GetMassCut()) retval=kTRUE;
2016 pdg3[0]=211; pdg3[1]=321; pdg3[2]=2212;
2017 minv = fMassCalc3->InvMass(nprongs,pdg3);
2018 if(TMath::Abs(minv-mPDG)<fCutsLctopKpi->GetMassCut()) retval=kTRUE;
2021 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
2022 pdg2[0]=211; pdg2[1]=421; // in twoTrackArrayCasc we put the pion first
2023 mPDG=TDatabasePDG::Instance()->GetParticle(413)->Mass();
2024 minv = fMassCalc2->InvMass(nprongs,pdg2);
2025 if(TMath::Abs(minv-mPDG)<fCutsDStartoKpipi->GetMassCut()) retval=kTRUE;
2027 case 4: // D0->Kpipipi without PID
2028 fMassCalc4->SetPxPyPzProngs(nprongs,px,py,pz);
2029 pdg4[0]=321; pdg4[1]=211; pdg4[2]=211; pdg4[3]=211;
2030 mPDG=TDatabasePDG::Instance()->GetParticle(421)->Mass();
2031 minv = fMassCalc4->InvMass(nprongs,pdg4);
2032 if(TMath::Abs(minv-mPDG)<fCutsD0toKpipipi->GetMassCut()) retval=kTRUE;
2033 pdg4[0]=211; pdg4[1]=321; pdg4[2]=211; pdg4[3]=211;
2034 mPDG=TDatabasePDG::Instance()->GetParticle(421)->Mass();
2035 minv = fMassCalc4->InvMass(nprongs,pdg4);
2036 if(TMath::Abs(minv-mPDG)<fCutsD0toKpipipi->GetMassCut()) retval=kTRUE;
2037 pdg4[0]=211; pdg4[1]=211; pdg4[2]=321; pdg4[3]=211;
2038 mPDG=TDatabasePDG::Instance()->GetParticle(421)->Mass();
2039 minv = fMassCalc4->InvMass(nprongs,pdg4);
2040 if(TMath::Abs(minv-mPDG)<fCutsD0toKpipipi->GetMassCut()) retval=kTRUE;
2041 pdg4[0]=211; pdg4[1]=211; pdg4[2]=211; pdg4[3]=321;
2042 mPDG=TDatabasePDG::Instance()->GetParticle(421)->Mass();
2043 minv = fMassCalc4->InvMass(nprongs,pdg4);
2044 if(TMath::Abs(minv-mPDG)<fCutsD0toKpipipi->GetMassCut()) retval=kTRUE;
2047 printf("SelectInvMass(): wrong decay selection\n");
2053 //-----------------------------------------------------------------------------
2054 void AliAnalysisVertexingHF::SelectTracksAndCopyVertex(const AliVEvent *event,
2056 TObjArray &seleTrksArray,Int_t &nSeleTrks,
2057 UChar_t *seleFlags,Int_t *evtNumber)
2059 // Apply single-track preselection.
2060 // Fill a TObjArray with selected tracks (for displaced vertices or
2061 // soft pion from D*). Selection flag stored in seleFlags.
2062 // Create the AliESDVertex object (convert from AliAODVertex if necessary)
2063 // In case of AOD input, also fill fAODMap for track index<->ID
2065 const AliVVertex *vprimary = event->GetPrimaryVertex();
2067 if(fV1) { delete fV1; fV1=NULL; }
2068 if(fAODMap) { delete fAODMap; fAODMap=NULL; }
2071 UShort_t *indices = 0;
2072 Double_t pos[3],cov[6];
2074 if(!fInputAOD) { // ESD
2075 fV1 = new AliESDVertex(*((AliESDVertex*)vprimary));
2077 vprimary->GetXYZ(pos);
2078 vprimary->GetCovarianceMatrix(cov);
2079 fV1 = new AliESDVertex(pos,cov,100.,100,vprimary->GetName());
2080 indices = new UShort_t[event->GetNumberOfTracks()];
2081 fAODMapSize = 100000;
2082 fAODMap = new Int_t[fAODMapSize];
2086 Int_t entries = (Int_t)event->GetNumberOfTracks();
2087 Bool_t okDisplaced=kFALSE,okSoftPi=kFALSE;
2090 // transfer ITS tracks from event to arrays
2091 for(Int_t i=0; i<entries; i++) {
2093 track = (AliVTrack*)event->GetTrack(i);
2095 // skip pure ITS SA tracks
2096 if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
2098 // skip tracks without ITS
2099 if(!(track->GetStatus()&AliESDtrack::kITSin)) continue;
2101 // TEMPORARY: check that the cov matrix is there
2102 Double_t covtest[21];
2103 if(!track->GetCovarianceXYZPxPyPz(covtest)) continue;
2107 AliAODTrack *aodt = (AliAODTrack*)track;
2108 if(aodt->GetUsedForPrimVtxFit()) {
2109 indices[nindices]=aodt->GetID(); nindices++;
2111 fAODMap[(Int_t)aodt->GetID()] = i;
2114 AliESDtrack *esdt = 0;
2117 esdt = (AliESDtrack*)track;
2119 esdt = new AliESDtrack(track);
2122 // single track selection
2123 okDisplaced=kFALSE; okSoftPi=kFALSE;
2124 if(fMixEvent && i<trkEntries){
2125 evtNumber[i]=((AliMixedEvent*)event)->EventIndex(i);
2126 const AliVVertex* eventVtx=((AliMixedEvent*)event)->GetEventVertex(i);
2127 Double_t vtxPos[3],primPos[3],primCov[6],trasl[3];
2128 eventVtx->GetXYZ(vtxPos);
2129 vprimary->GetXYZ(primPos);
2130 eventVtx->GetCovarianceMatrix(primCov);
2131 for(Int_t ind=0;ind<3;ind++){
2132 trasl[ind]=vtxPos[ind]-primPos[ind];
2135 Bool_t isTransl=esdt->Translate(trasl,primCov);
2143 if(SingleTrkCuts(esdt,okDisplaced,okSoftPi) && nSeleTrks<trkEntries) {
2144 seleTrksArray.AddLast(esdt);
2145 seleFlags[nSeleTrks]=0;
2146 if(okDisplaced) SETBIT(seleFlags[nSeleTrks],kBitDispl);
2147 if(okSoftPi) SETBIT(seleFlags[nSeleTrks],kBitSoftPi);
2150 if(fInputAOD) delete esdt;
2155 } // end loop on tracks
2157 // primary vertex from AOD
2159 delete fV1; fV1=NULL;
2160 vprimary->GetXYZ(pos);
2161 vprimary->GetCovarianceMatrix(cov);
2162 Double_t chi2toNDF = vprimary->GetChi2perNDF();
2163 Int_t ncontr=nindices;
2164 if(!strcmp(vprimary->GetTitle(),"VertexerTracksWithContraint")) ncontr += 1;
2165 Double_t chi2=chi2toNDF*(2.*(Double_t)ncontr-3.);
2166 fV1 = new AliESDVertex(pos,cov,chi2,ncontr,vprimary->GetName());
2167 fV1->SetTitle(vprimary->GetTitle());
2168 fV1->SetIndices(nindices,indices);
2170 if(indices) { delete [] indices; indices=NULL; }
2175 //-----------------------------------------------------------------------------
2176 Bool_t AliAnalysisVertexingHF::SingleTrkCuts(AliESDtrack *trk,
2177 Bool_t &okDisplaced,Bool_t &okSoftPi) const
2179 // Check if track passes some kinematical cuts
2181 // this is needed to store the impact parameters
2182 trk->RelateToVertex(fV1,fBzkG,kVeryBig);
2186 // Track selection, displaced tracks
2189 selectInfo = fTrackFilter->IsSelected(trk);
2191 if(selectInfo) okDisplaced=kTRUE;
2193 // Track selection, soft pions
2195 if(fDstar && fTrackFilterSoftPi) {
2196 selectInfo = fTrackFilterSoftPi->IsSelected(trk);
2198 if(selectInfo) okSoftPi=kTRUE;
2200 if(okDisplaced || okSoftPi) return kTRUE;
2206 //-----------------------------------------------------------------------------
2207 AliAODv0* AliAnalysisVertexingHF::TransformESDv0toAODv0(AliESDv0 *esdV0, TObjArray *twoTrackArrayV0){
2209 // Transform ESDv0 to AODv0
2211 // this function takes the ESDv0 vertex, computes the DCA variables from the ESDv0
2212 // and creates an AODv0 out of them
2214 Double_t vertex[3]; esdV0->GetXYZ(vertex[0],vertex[1],vertex[2]);
2215 AliAODVertex *vertexV0 = new AliAODVertex(vertex,esdV0->GetChi2V0(),AliAODVertex::kV0,2);
2217 // create the v0 neutral track to compute the DCA to the primary vertex
2218 Double_t xyz[3], pxpypz[3];
2220 esdV0->PxPyPz(pxpypz);
2221 Double_t cv[21]; for(int i=0; i<21; i++) cv[i]=0;
2222 AliNeutralTrackParam *trackesdV0 = new AliNeutralTrackParam(xyz,pxpypz,cv,0);
2223 if(!trackesdV0) return 0;
2224 Double_t d0z0[2],covd0z0[3];
2225 AliAODVertex *primVertexAOD = PrimaryVertex();
2226 trackesdV0->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2227 Double_t dcaV0ToPrimVertex = TMath::Sqrt(covd0z0[0]);
2228 // get the v0 daughters to compute their DCA to the v0 vertex and get their momentum
2229 Double_t dcaV0DaughterToPrimVertex[2];
2230 AliExternalTrackParam *posV0track = (AliExternalTrackParam*)twoTrackArrayV0->UncheckedAt(0);
2231 AliExternalTrackParam *negV0track = (AliExternalTrackParam*)twoTrackArrayV0->UncheckedAt(1);
2232 if( !posV0track || !negV0track) {
2233 if(trackesdV0) {delete trackesdV0; trackesdV0=NULL;}
2236 posV0track->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2237 // if ( covd0z0[0]<=0.) dcaV0DaughterToPrimVertex[0] = 0;
2239 dcaV0DaughterToPrimVertex[0] = TMath::Sqrt(covd0z0[0]);
2240 negV0track->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2241 // if ( covd0z0[0]<=0.)dcaV0DaughterToPrimVertex[1] = 0;
2243 dcaV0DaughterToPrimVertex[1] = TMath::Sqrt(covd0z0[0]);
2244 Double_t dcaV0Daughters = esdV0->GetDcaV0Daughters();
2245 Double_t pmom[3],nmom[3];
2246 esdV0->GetNPxPyPz(nmom[0],nmom[1],nmom[2]);
2247 esdV0->GetPPxPyPz(pmom[0],pmom[1],pmom[2]);
2249 AliAODv0 *aodV0 = new AliAODv0(vertexV0,dcaV0Daughters,dcaV0ToPrimVertex,pmom,nmom,dcaV0DaughterToPrimVertex);
2250 aodV0->SetOnFlyStatus(esdV0->GetOnFlyStatus());
2252 if(trackesdV0) {delete trackesdV0; trackesdV0=NULL;}
2253 if(primVertexAOD) {delete primVertexAOD; primVertexAOD=NULL;}
2257 //-----------------------------------------------------------------------------