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 **************************************************************************/
18 //----------------------------------------------------------------------------
19 // Implementation of the heavy-flavour vertexing analysis class
20 // Candidates are stored in the AOD as objects deriving from AliAODRecoDecay.
21 // To be used as a task of AliAnalysisManager by means of the interface
22 // class AliAnalysisTaskSEVertexingHF.
23 // An example of usage in the macro AliAnalysisTaskSEVertexingHFTest.C.
25 // Contact: andrea.dainese@pd.infn.it
26 // Contributors: E.Bruna, G.E.Bruno, A.Dainese, C.Di Gliglio,
27 // F.Prino, R.Romita, X.M.Zhang
28 //----------------------------------------------------------------------------
29 #include <Riostream.h>
31 #include <TDatabasePDG.h>
35 #include "AliVEvent.h"
36 #include "AliVVertex.h"
37 #include "AliVTrack.h"
38 #include "AliVertexerTracks.h"
39 #include "AliKFVertex.h"
40 #include "AliESDEvent.h"
41 #include "AliESDVertex.h"
42 #include "AliExternalTrackParam.h"
43 #include "AliNeutralTrackParam.h"
44 #include "AliESDtrack.h"
45 #include "AliESDtrackCuts.h"
46 #include "AliAODEvent.h"
47 #include "AliPIDResponse.h"
48 #include "AliAODRecoDecay.h"
49 #include "AliAODRecoDecayHF.h"
50 #include "AliAODRecoDecayHF2Prong.h"
51 #include "AliAODRecoDecayHF3Prong.h"
52 #include "AliAODRecoDecayHF4Prong.h"
53 #include "AliAODRecoCascadeHF.h"
54 #include "AliRDHFCutsD0toKpi.h"
55 #include "AliRDHFCutsJpsitoee.h"
56 #include "AliRDHFCutsDplustoKpipi.h"
57 #include "AliRDHFCutsDstoKKpi.h"
58 #include "AliRDHFCutsLctopKpi.h"
59 #include "AliRDHFCutsLctoV0.h"
60 #include "AliRDHFCutsD0toKpipipi.h"
61 #include "AliRDHFCutsDStartoKpipi.h"
62 #include "AliAnalysisFilter.h"
63 #include "AliAnalysisVertexingHF.h"
64 #include "AliMixedEvent.h"
67 #include "AliCodeTimer.h"
70 ClassImp(AliAnalysisVertexingHF)
72 //----------------------------------------------------------------------------
73 AliAnalysisVertexingHF::AliAnalysisVertexingHF():
79 fSecVtxWithKF(kFALSE),
80 fRecoPrimVtxSkippingTrks(kFALSE),
81 fRmTrksFromPrimVtx(kFALSE),
90 fLikeSign3prong(kFALSE),
93 fUseKaonPIDfor3Prong(kFALSE),
94 fnSigmaTOFKaonLow(5.),
96 fMaxCentPercentileForTightCuts(-9999),
98 fTrackFilter2prongCentral(0x0),
99 fTrackFilter3prongCentral(0x0),
100 fTrackFilterSoftPi(0x0),
103 fCutsDplustoKpipi(0x0),
107 fCutsD0toKpipipi(0x0),
108 fCutsDStartoKpipi(0x0),
110 fFindVertexForDstar(kTRUE),
111 fFindVertexForCascades(kTRUE),
112 fV0TypeForCascadeVertex(0),
113 fMassCutBeforeVertexing(kFALSE),
117 fOKInvMassD0(kFALSE),
118 fOKInvMassJpsi(kFALSE),
119 fOKInvMassDplus(kFALSE),
120 fOKInvMassDs(kFALSE),
121 fOKInvMassLc(kFALSE),
122 fOKInvMassDstar(kFALSE),
123 fOKInvMassD0to4p(kFALSE),
124 fOKInvMassLctoV0(kFALSE),
134 // Default constructor
136 Double_t d02[2]={0.,0.};
137 Double_t d03[3]={0.,0.,0.};
138 Double_t d04[4]={0.,0.,0.,0.};
139 fMassCalc2 = new AliAODRecoDecay(0x0,2,0,d02);
140 fMassCalc3 = new AliAODRecoDecay(0x0,3,1,d03);
141 fMassCalc4 = new AliAODRecoDecay(0x0,4,0,d04);
144 //--------------------------------------------------------------------------
145 AliAnalysisVertexingHF::AliAnalysisVertexingHF(const AliAnalysisVertexingHF &source) :
147 fInputAOD(source.fInputAOD),
148 fAODMapSize(source.fAODMapSize),
149 fAODMap(source.fAODMap),
150 fVertexerTracks(source.fVertexerTracks),
152 fSecVtxWithKF(source.fSecVtxWithKF),
153 fRecoPrimVtxSkippingTrks(source.fRecoPrimVtxSkippingTrks),
154 fRmTrksFromPrimVtx(source.fRmTrksFromPrimVtx),
156 fD0toKpi(source.fD0toKpi),
157 fJPSItoEle(source.fJPSItoEle),
158 f3Prong(source.f3Prong),
159 f4Prong(source.f4Prong),
160 fDstar(source.fDstar),
161 fCascades(source.fCascades),
162 fLikeSign(source.fLikeSign),
163 fLikeSign3prong(source.fLikeSign3prong),
164 fMixEvent(source.fMixEvent),
165 fPidResponse(source.fPidResponse),
166 fUseKaonPIDfor3Prong(source.fUseKaonPIDfor3Prong),
167 fnSigmaTOFKaonLow(source.fnSigmaTOFKaonLow),
168 fnSigmaTOFKaonHi(source.fnSigmaTOFKaonHi),
169 fMaxCentPercentileForTightCuts(source.fMaxCentPercentileForTightCuts),
170 fTrackFilter(source.fTrackFilter),
171 fTrackFilter2prongCentral(source.fTrackFilter2prongCentral),
172 fTrackFilter3prongCentral(source.fTrackFilter3prongCentral),
173 fTrackFilterSoftPi(source.fTrackFilterSoftPi),
174 fCutsD0toKpi(source.fCutsD0toKpi),
175 fCutsJpsitoee(source.fCutsJpsitoee),
176 fCutsDplustoKpipi(source.fCutsDplustoKpipi),
177 fCutsDstoKKpi(source.fCutsDstoKKpi),
178 fCutsLctopKpi(source.fCutsLctopKpi),
179 fCutsLctoV0(source.fCutsLctoV0),
180 fCutsD0toKpipipi(source.fCutsD0toKpipipi),
181 fCutsDStartoKpipi(source.fCutsDStartoKpipi),
182 fListOfCuts(source.fListOfCuts),
183 fFindVertexForDstar(source.fFindVertexForDstar),
184 fFindVertexForCascades(source.fFindVertexForCascades),
185 fV0TypeForCascadeVertex(source.fV0TypeForCascadeVertex),
186 fMassCutBeforeVertexing(source.fMassCutBeforeVertexing),
187 fMassCalc2(source.fMassCalc2),
188 fMassCalc3(source.fMassCalc3),
189 fMassCalc4(source.fMassCalc4),
190 fOKInvMassD0(source.fOKInvMassD0),
191 fOKInvMassJpsi(source.fOKInvMassJpsi),
192 fOKInvMassDplus(source.fOKInvMassDplus),
193 fOKInvMassDs(source.fOKInvMassDs),
194 fOKInvMassLc(source.fOKInvMassLc),
195 fOKInvMassDstar(source.fOKInvMassDstar),
196 fOKInvMassD0to4p(source.fOKInvMassD0to4p),
197 fOKInvMassLctoV0(source.fOKInvMassLctoV0),
200 fMassDzero(source.fMassDzero),
201 fMassDplus(source.fMassDplus),
202 fMassDs(source.fMassDs),
203 fMassLambdaC(source.fMassLambdaC),
204 fMassDstar(source.fMassDstar),
205 fMassJpsi(source.fMassJpsi)
211 //--------------------------------------------------------------------------
212 AliAnalysisVertexingHF &AliAnalysisVertexingHF::operator=(const AliAnalysisVertexingHF &source)
215 // assignment operator
217 if(&source == this) return *this;
218 fInputAOD = source.fInputAOD;
219 fAODMapSize = source.fAODMapSize;
220 fVertexerTracks = source.fVertexerTracks;
221 fBzkG = source.fBzkG;
222 fSecVtxWithKF = source.fSecVtxWithKF;
223 fRecoPrimVtxSkippingTrks = source.fRecoPrimVtxSkippingTrks;
224 fRmTrksFromPrimVtx = source.fRmTrksFromPrimVtx;
226 fD0toKpi = source.fD0toKpi;
227 fJPSItoEle = source.fJPSItoEle;
228 f3Prong = source.f3Prong;
229 f4Prong = source.f4Prong;
230 fDstar = source.fDstar;
231 fCascades = source.fCascades;
232 fLikeSign = source.fLikeSign;
233 fLikeSign3prong = source.fLikeSign3prong;
234 fMixEvent = source.fMixEvent;
235 fPidResponse = source.fPidResponse;
236 fUseKaonPIDfor3Prong = source.fUseKaonPIDfor3Prong;
237 fnSigmaTOFKaonLow = source.fnSigmaTOFKaonLow;
238 fnSigmaTOFKaonHi = source.fnSigmaTOFKaonHi;
239 fMaxCentPercentileForTightCuts = source.fMaxCentPercentileForTightCuts;
240 fTrackFilter = source.fTrackFilter;
241 fTrackFilter2prongCentral = source.fTrackFilter2prongCentral;
242 fTrackFilter3prongCentral = source.fTrackFilter3prongCentral;
243 fTrackFilterSoftPi = source.fTrackFilterSoftPi;
244 fCutsD0toKpi = source.fCutsD0toKpi;
245 fCutsJpsitoee = source.fCutsJpsitoee;
246 fCutsDplustoKpipi = source.fCutsDplustoKpipi;
247 fCutsDstoKKpi = source.fCutsDstoKKpi;
248 fCutsLctopKpi = source.fCutsLctopKpi;
249 fCutsLctoV0 = source.fCutsLctoV0;
250 fCutsD0toKpipipi = source.fCutsD0toKpipipi;
251 fCutsDStartoKpipi = source.fCutsDStartoKpipi;
252 fListOfCuts = source.fListOfCuts;
253 fFindVertexForDstar = source.fFindVertexForDstar;
254 fFindVertexForCascades = source.fFindVertexForCascades;
255 fV0TypeForCascadeVertex = source.fV0TypeForCascadeVertex;
256 fMassCutBeforeVertexing = source.fMassCutBeforeVertexing;
257 fMassCalc2 = source.fMassCalc2;
258 fMassCalc3 = source.fMassCalc3;
259 fMassCalc4 = source.fMassCalc4;
260 fOKInvMassD0 = source.fOKInvMassD0;
261 fOKInvMassJpsi = source.fOKInvMassJpsi;
262 fOKInvMassDplus = source.fOKInvMassDplus;
263 fOKInvMassDs = source.fOKInvMassDs;
264 fOKInvMassLc = source.fOKInvMassLc;
265 fOKInvMassDstar = source.fOKInvMassDstar;
266 fOKInvMassD0to4p = source.fOKInvMassD0to4p;
267 fOKInvMassLctoV0 = source.fOKInvMassLctoV0;
268 fMassDzero = source.fMassDzero;
269 fMassDplus = source.fMassDplus;
270 fMassDs = source.fMassDs;
271 fMassLambdaC = source.fMassLambdaC;
272 fMassDstar = source.fMassDstar;
273 fMassJpsi = source.fMassJpsi;
277 //----------------------------------------------------------------------------
278 AliAnalysisVertexingHF::~AliAnalysisVertexingHF() {
280 if(fV1) { delete fV1; fV1=0; }
281 delete fVertexerTracks;
282 if(fTrackFilter) { delete fTrackFilter; fTrackFilter=0; }
283 if(fTrackFilter2prongCentral) { delete fTrackFilter2prongCentral; fTrackFilter2prongCentral=0; }
284 if(fTrackFilter3prongCentral) { delete fTrackFilter3prongCentral; fTrackFilter3prongCentral=0; }
285 if(fTrackFilterSoftPi) { delete fTrackFilterSoftPi; fTrackFilterSoftPi=0; }
286 if(fCutsD0toKpi) { delete fCutsD0toKpi; fCutsD0toKpi=0; }
287 if(fCutsJpsitoee) { delete fCutsJpsitoee; fCutsJpsitoee=0; }
288 if(fCutsDplustoKpipi) { delete fCutsDplustoKpipi; fCutsDplustoKpipi=0; }
289 if(fCutsDstoKKpi) { delete fCutsDstoKKpi; fCutsDstoKKpi=0; }
290 if(fCutsLctopKpi) { delete fCutsLctopKpi; fCutsLctopKpi=0; }
291 if(fCutsLctoV0) { delete fCutsLctoV0; fCutsLctoV0=0; }
292 if(fCutsD0toKpipipi) { delete fCutsD0toKpipipi; fCutsD0toKpipipi=0; }
293 if(fCutsDStartoKpipi) { delete fCutsDStartoKpipi; fCutsDStartoKpipi=0; }
294 if(fAODMap) { delete [] fAODMap; fAODMap=0; }
295 if(fMassCalc2) { delete fMassCalc2; fMassCalc2=0; }
296 if(fMassCalc3) { delete fMassCalc3; fMassCalc3=0; }
297 if(fMassCalc4) { delete fMassCalc4; fMassCalc4=0; }
299 //----------------------------------------------------------------------------
300 TList *AliAnalysisVertexingHF::FillListOfCuts() {
301 // Fill list of analysis cuts
303 TList *list = new TList();
305 list->SetName("ListOfCuts");
308 AliRDHFCutsD0toKpi *cutsD0toKpi = new AliRDHFCutsD0toKpi(*fCutsD0toKpi);
309 list->Add(cutsD0toKpi);
312 AliRDHFCutsJpsitoee *cutsJpsitoee = new AliRDHFCutsJpsitoee(*fCutsJpsitoee);
313 list->Add(cutsJpsitoee);
315 if(fCutsDplustoKpipi) {
316 AliRDHFCutsDplustoKpipi *cutsDplustoKpipi = new AliRDHFCutsDplustoKpipi(*fCutsDplustoKpipi);
317 list->Add(cutsDplustoKpipi);
320 AliRDHFCutsDstoKKpi *cutsDstoKKpi = new AliRDHFCutsDstoKKpi(*fCutsDstoKKpi);
321 list->Add(cutsDstoKKpi);
324 AliRDHFCutsLctopKpi *cutsLctopKpi = new AliRDHFCutsLctopKpi(*fCutsLctopKpi);
325 list->Add(cutsLctopKpi);
328 AliRDHFCutsLctoV0 *cutsLctoV0 = new AliRDHFCutsLctoV0(*fCutsLctoV0);
329 list->Add(cutsLctoV0);
331 if(fCutsD0toKpipipi) {
332 AliRDHFCutsD0toKpipipi *cutsD0toKpipipi = new AliRDHFCutsD0toKpipipi(*fCutsD0toKpipipi);
333 list->Add(cutsD0toKpipipi);
335 if(fCutsDStartoKpipi) {
336 AliRDHFCutsDStartoKpipi *cutsDStartoKpipi = new AliRDHFCutsDStartoKpipi(*fCutsDStartoKpipi);
337 list->Add(cutsDStartoKpipi);
340 //___ Check consitstency of cuts between vertexer and analysis tasks
341 Bool_t bCutsOk = CheckCutsConsistency();
342 if (bCutsOk == kFALSE) {AliFatal("AliAnalysisVertexingHF::FillListOfCuts vertexing and the analysis task cuts are not consistent!");}
344 // keep a pointer to the list
349 //----------------------------------------------------------------------------
350 void AliAnalysisVertexingHF::FindCandidates(AliVEvent *event,
351 TClonesArray *aodVerticesHFTClArr,
352 TClonesArray *aodD0toKpiTClArr,
353 TClonesArray *aodJPSItoEleTClArr,
354 TClonesArray *aodCharm3ProngTClArr,
355 TClonesArray *aodCharm4ProngTClArr,
356 TClonesArray *aodDstarTClArr,
357 TClonesArray *aodCascadesTClArr,
358 TClonesArray *aodLikeSign2ProngTClArr,
359 TClonesArray *aodLikeSign3ProngTClArr)
361 // Find heavy-flavour vertex candidates
363 // Output: AOD (additional branches added)
364 //AliCodeTimerAuto("",0);
367 TString evtype = event->IsA()->GetName();
368 fInputAOD = ((evtype=="AliAODEvent") ? kTRUE : kFALSE);
369 } // if we do mixing AliVEvent is a AliMixedEvent
372 AliDebug(2,"Creating HF candidates from AOD");
374 AliDebug(2,"Creating HF candidates from ESD");
377 if(!aodVerticesHFTClArr) {
378 printf("ERROR: no aodVerticesHFTClArr");
381 if((fD0toKpi || fDstar) && !aodD0toKpiTClArr) {
382 printf("ERROR: no aodD0toKpiTClArr");
385 if(fJPSItoEle && !aodJPSItoEleTClArr) {
386 printf("ERROR: no aodJPSItoEleTClArr");
389 if(f3Prong && !aodCharm3ProngTClArr) {
390 printf("ERROR: no aodCharm3ProngTClArr");
393 if(f4Prong && !aodCharm4ProngTClArr) {
394 printf("ERROR: no aodCharm4ProngTClArr");
397 if(fDstar && !aodDstarTClArr) {
398 printf("ERROR: no aodDstarTClArr");
401 if(fCascades && !aodCascadesTClArr){
402 printf("ERROR: no aodCascadesTClArr ");
405 if(fLikeSign && !aodLikeSign2ProngTClArr) {
406 printf("ERROR: no aodLikeSign2ProngTClArr");
409 if(fLikeSign3prong && f3Prong && !aodLikeSign3ProngTClArr) {
410 printf("ERROR: no aodLikeSign3ProngTClArr");
414 // delete candidates from previous event and create references
415 Int_t iVerticesHF=0,iD0toKpi=0,iJPSItoEle=0,i3Prong=0,i4Prong=0,iDstar=0,iCascades=0,iLikeSign2Prong=0,iLikeSign3Prong=0;
416 aodVerticesHFTClArr->Delete();
417 iVerticesHF = aodVerticesHFTClArr->GetEntriesFast();
418 TClonesArray &verticesHFRef = *aodVerticesHFTClArr;
419 if(fD0toKpi || fDstar) {
420 aodD0toKpiTClArr->Delete();
421 iD0toKpi = aodD0toKpiTClArr->GetEntriesFast();
424 aodJPSItoEleTClArr->Delete();
425 iJPSItoEle = aodJPSItoEleTClArr->GetEntriesFast();
428 aodCharm3ProngTClArr->Delete();
429 i3Prong = aodCharm3ProngTClArr->GetEntriesFast();
432 aodCharm4ProngTClArr->Delete();
433 i4Prong = aodCharm4ProngTClArr->GetEntriesFast();
436 aodDstarTClArr->Delete();
437 iDstar = aodDstarTClArr->GetEntriesFast();
440 aodCascadesTClArr->Delete();
441 iCascades = aodCascadesTClArr->GetEntriesFast();
444 aodLikeSign2ProngTClArr->Delete();
445 iLikeSign2Prong = aodLikeSign2ProngTClArr->GetEntriesFast();
447 if(fLikeSign3prong && f3Prong) {
448 aodLikeSign3ProngTClArr->Delete();
449 iLikeSign3Prong = aodLikeSign3ProngTClArr->GetEntriesFast();
452 TClonesArray &aodD0toKpiRef = *aodD0toKpiTClArr;
453 TClonesArray &aodJPSItoEleRef = *aodJPSItoEleTClArr;
454 TClonesArray &aodCharm3ProngRef = *aodCharm3ProngTClArr;
455 TClonesArray &aodCharm4ProngRef = *aodCharm4ProngTClArr;
456 TClonesArray &aodDstarRef = *aodDstarTClArr;
457 TClonesArray &aodCascadesRef = *aodCascadesTClArr;
458 TClonesArray &aodLikeSign2ProngRef = *aodLikeSign2ProngTClArr;
459 TClonesArray &aodLikeSign3ProngRef = *aodLikeSign3ProngTClArr;
462 AliAODRecoDecayHF2Prong *io2Prong = 0;
463 AliAODRecoDecayHF3Prong *io3Prong = 0;
464 AliAODRecoDecayHF4Prong *io4Prong = 0;
465 AliAODRecoCascadeHF *ioCascade = 0;
467 Int_t iTrkP1,iTrkP2,iTrkN1,iTrkN2,iTrkSoftPi,trkEntries,iv0,nv0;
468 Double_t xdummy,ydummy,dcap1n1,dcap1n2,dcap2n1,dcap1p2,dcan1n2,dcap2n2,dcaV0,dcaCasc;
469 Bool_t okD0=kFALSE,okJPSI=kFALSE,ok3Prong=kFALSE,ok4Prong=kFALSE;
470 Bool_t okDstar=kFALSE,okD0fromDstar=kFALSE;
471 Bool_t okCascades=kFALSE;
472 AliESDtrack *postrack1 = 0;
473 AliESDtrack *postrack2 = 0;
474 AliESDtrack *negtrack1 = 0;
475 AliESDtrack *negtrack2 = 0;
476 AliESDtrack *trackPi = 0;
477 Double_t mompos1[3],mompos2[3],momneg1[3],momneg2[3];
478 // AliESDtrack *posV0track = 0;
479 // AliESDtrack *negV0track = 0;
480 Float_t dcaMax = fCutsD0toKpi->GetDCACut();
481 if(fCutsJpsitoee) dcaMax=TMath::Max(dcaMax,fCutsJpsitoee->GetDCACut());
482 if(fCutsDplustoKpipi) dcaMax=TMath::Max(dcaMax,fCutsDplustoKpipi->GetDCACut());
483 if(fCutsDstoKKpi) dcaMax=TMath::Max(dcaMax,fCutsDstoKKpi->GetDCACut());
484 if(fCutsLctopKpi) dcaMax=TMath::Max(dcaMax,fCutsLctopKpi->GetDCACut());
485 if(fCutsD0toKpipipi) dcaMax=TMath::Max(dcaMax,fCutsD0toKpipipi->GetDCACut());
486 if(fCutsDStartoKpipi) dcaMax=TMath::Max(dcaMax,fCutsDStartoKpipi->GetDCACut());
488 AliDebug(2,Form(" dca cut set to %f cm",dcaMax));
492 fBzkG = (Double_t)event->GetMagneticField();
493 if(!fVertexerTracks){
494 fVertexerTracks=new AliVertexerTracks(fBzkG);
496 Double_t oldField=fVertexerTracks->GetFieldkG();
497 if(oldField!=fBzkG) fVertexerTracks->SetFieldkG(fBzkG);
500 trkEntries = (Int_t)event->GetNumberOfTracks();
501 AliDebug(1,Form(" Number of tracks: %d",trkEntries));
502 fnTrksTotal += trkEntries;
504 nv0 = (Int_t)event->GetNumberOfV0s();
505 AliDebug(1,Form(" Number of V0s: %d",nv0));
507 if( trkEntries<2 && (trkEntries<1 || nv0<1) ) {
508 AliDebug(1,Form(" Not enough tracks: %d",trkEntries));
512 // event selection + PID configuration
513 if(!fCutsD0toKpi->IsEventSelected(event)) return;
514 if(fCutsJpsitoee) fCutsJpsitoee->SetupPID(event);
515 if(fCutsDplustoKpipi) fCutsDplustoKpipi->SetupPID(event);
516 if(fCutsDstoKKpi) fCutsDstoKKpi->SetupPID(event);
517 if(fCutsLctopKpi) fCutsLctopKpi->SetupPID(event);
518 if(fCutsLctoV0) fCutsLctoV0->SetupPID(event);
519 if(fCutsD0toKpipipi) fCutsD0toKpipipi->SetupPID(event);
520 if(fCutsDStartoKpipi) fCutsDStartoKpipi->SetupPID(event);
522 // call function that applies sigle-track selection,
523 // for displaced tracks and soft pions (both charges) for D*,
524 // and retrieves primary vertex
525 TObjArray seleTrksArray(trkEntries);
526 TObjArray tracksAtVertex(trkEntries);
527 UChar_t *seleFlags = new UChar_t[trkEntries]; // bit 0: displaced, bit 1: softpi, bit 2: 3 prong
529 Int_t *evtNumber = new Int_t[trkEntries];
530 SelectTracksAndCopyVertex(event,trkEntries,seleTrksArray,tracksAtVertex,nSeleTrks,seleFlags,evtNumber);
532 AliDebug(1,Form(" Selected tracks: %d",nSeleTrks));
533 fnSeleTrksTotal += nSeleTrks;
536 TObjArray *twoTrackArray1 = new TObjArray(2);
537 TObjArray *twoTrackArray2 = new TObjArray(2);
538 TObjArray *twoTrackArrayV0 = new TObjArray(2);
539 TObjArray *twoTrackArrayCasc = new TObjArray(2);
540 TObjArray *threeTrackArray = new TObjArray(3);
541 TObjArray *fourTrackArray = new TObjArray(4);
544 Bool_t isLikeSign2Prong=kFALSE,isLikeSign3Prong=kFALSE;
546 AliAODRecoDecayHF *rd = 0;
547 AliAODRecoCascadeHF *rc = 0;
551 Bool_t massCutOK=kTRUE;
553 // LOOP ON POSITIVE TRACKS
554 for(iTrkP1=0; iTrkP1<nSeleTrks; iTrkP1++) {
556 //if(iTrkP1%1==0) AliDebug(1,Form(" 1st loop on pos: track number %d of %d",iTrkP1,nSeleTrks));
557 //if(iTrkP1%1==0) printf(" 1st loop on pos: track number %d of %d\n",iTrkP1,nSeleTrks);
559 // get track from tracks array
560 postrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP1);
561 if(!TESTBIT(seleFlags[iTrkP1],kBitDispl)) continue;
562 postrack1->GetPxPyPz(mompos1);
564 // Make cascades with V0+track
568 for(iv0=0; iv0<nv0; iv0++){
570 //AliDebug(1,Form(" loop on v0s for track number %d and v0 number %d",iTrkP1,iv0));
574 v0 = ((AliAODEvent*)event)->GetV0(iv0);
576 esdV0 = ((AliESDEvent*)event)->GetV0(iv0);
578 if ( (!v0 || !v0->IsA()->InheritsFrom("AliAODv0") ) &&
579 (!esdV0 || !esdV0->IsA()->InheritsFrom("AliESDv0") ) ) continue;
581 if ( v0 && ((v0->GetOnFlyStatus() == kTRUE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOfflineV0s) ||
582 (v0->GetOnFlyStatus() == kFALSE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOnTheFlyV0s)) ) continue;
584 if ( esdV0 && ((esdV0->GetOnFlyStatus() == kTRUE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOfflineV0s) ||
585 ( esdV0->GetOnFlyStatus() == kFALSE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOnTheFlyV0s)) ) continue;
587 // Get the tracks that form the V0
588 // ( parameters at primary vertex )
589 // and define an AliExternalTrackParam out of them
590 AliExternalTrackParam * posV0track;
591 AliExternalTrackParam * negV0track;
594 AliAODTrack *posVV0track = (AliAODTrack*)(v0->GetDaughter(0));
595 AliAODTrack *negVV0track = (AliAODTrack*)(v0->GetDaughter(1));
596 if( !posVV0track || !negVV0track ) continue;
598 // Apply some basic V0 daughter criteria
600 // bachelor must not be a v0-track
601 if (posVV0track->GetID() == postrack1->GetID() ||
602 negVV0track->GetID() == postrack1->GetID()) continue;
603 // reject like-sign v0
604 if ( posVV0track->Charge() == negVV0track->Charge() ) continue;
605 // avoid ghost TPC tracks
606 if(!(posVV0track->GetStatus() & AliESDtrack::kTPCrefit) ||
607 !(negVV0track->GetStatus() & AliESDtrack::kTPCrefit)) continue;
608 // Get AliExternalTrackParam out of the AliAODTracks
609 Double_t xyz[3], pxpypz[3], cv[21]; Short_t sign;
610 posVV0track->PxPyPz(pxpypz); posVV0track->XvYvZv(xyz);
611 posVV0track->GetCovarianceXYZPxPyPz(cv); sign=posVV0track->Charge();
612 posV0track = new AliExternalTrackParam(xyz,pxpypz,cv,sign);
613 negVV0track->PxPyPz(pxpypz); negVV0track->XvYvZv(xyz);
614 negVV0track->GetCovarianceXYZPxPyPz(cv); sign=negVV0track->Charge();
615 negV0track = new AliExternalTrackParam(xyz,pxpypz,cv,sign);
617 AliESDtrack *posVV0track = (AliESDtrack*)(event->GetTrack( esdV0->GetPindex() ));
618 AliESDtrack *negVV0track = (AliESDtrack*)(event->GetTrack( esdV0->GetNindex() ));
619 if( !posVV0track || !negVV0track ) continue;
621 // Apply some basic V0 daughter criteria
623 // bachelor must not be a v0-track
624 if (posVV0track->GetID() == postrack1->GetID() ||
625 negVV0track->GetID() == postrack1->GetID()) continue;
626 // reject like-sign v0
627 if ( posVV0track->Charge() == negVV0track->Charge() ) continue;
628 // avoid ghost TPC tracks
629 if(!(posVV0track->GetStatus() & AliESDtrack::kTPCrefit) ||
630 !(negVV0track->GetStatus() & AliESDtrack::kTPCrefit)) continue;
631 // reject kinks (only necessary on AliESDtracks)
632 if (posVV0track->GetKinkIndex(0)>0 || negVV0track->GetKinkIndex(0)>0) continue;
633 // Get AliExternalTrackParam out of the AliESDtracks
634 posV0track = new AliExternalTrackParam(*posVV0track);
635 negV0track = new AliExternalTrackParam(*negVV0track);
637 // Define the AODv0 from ESDv0 if reading ESDs
638 v0 = TransformESDv0toAODv0(esdV0,twoTrackArrayV0);
640 if( !posV0track || !negV0track ){
641 AliDebug(1,Form(" Couldn't get the V0 daughters"));
645 // fill in the v0 two-external-track-param array
646 twoTrackArrayV0->AddAt(posV0track,0);
647 twoTrackArrayV0->AddAt(negV0track,1);
650 dcaV0 = v0->DcaV0Daughters();
652 // Define the V0 (neutral) track
653 AliNeutralTrackParam *trackV0;
655 const AliVTrack *trackVV0 = dynamic_cast<const AliVTrack*>(v0);
656 if(trackVV0) trackV0 = new AliNeutralTrackParam(trackVV0);
658 Double_t xyz[3], pxpypz[3];
660 esdV0->PxPyPz(pxpypz);
661 Double_t cv[21]; for(int i=0; i<21; i++) cv[i]=0;
662 trackV0 = new AliNeutralTrackParam(xyz,pxpypz,cv,0);
664 // Fill in the object array to create the cascade
665 twoTrackArrayCasc->AddAt(postrack1,0);
666 twoTrackArrayCasc->AddAt(trackV0,1);
667 // Compute the cascade vertex
668 AliAODVertex *vertexCasc = 0;
669 if(fFindVertexForCascades) {
670 // DCA between the two tracks
671 dcaCasc = postrack1->GetDCA(trackV0,fBzkG,xdummy,ydummy);
673 vertexCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
675 // assume Cascade decays at the primary vertex
676 Double_t pos[3],cov[6],chi2perNDF;
678 fV1->GetCovMatrix(cov);
679 chi2perNDF = fV1->GetChi2toNDF();
680 vertexCasc = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,2);
684 delete posV0track; posV0track=NULL;
685 delete negV0track; negV0track=NULL;
686 delete trackV0; trackV0=NULL;
687 if(!fInputAOD) {delete v0; v0=NULL;}
688 twoTrackArrayV0->Clear();
689 twoTrackArrayCasc->Clear();
693 // Create and store the Cascade if passed the cuts
694 ioCascade = MakeCascade(twoTrackArrayCasc,event,vertexCasc,v0,dcaCasc,okCascades);
695 if(okCascades && ioCascade) {
696 //AliDebug(1,Form("Storing a cascade object... "));
697 // add the vertex and the cascade to the AOD
698 AliAODVertex *vCasc = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexCasc);
699 rc = new(aodCascadesRef[iCascades++])AliAODRecoCascadeHF(*ioCascade);
700 rc->SetSecondaryVtx(vCasc);
701 vCasc->SetParent(rc);
702 rc->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
703 if(!fInputAOD) vCasc->AddDaughter(v0); // just to fill ref #0 ??
704 AddRefs(vCasc,rc,event,twoTrackArrayCasc); // add the track (proton)
705 vCasc->AddDaughter(v0); // fill the 2prong V0
709 delete posV0track; posV0track=NULL;
710 delete negV0track; negV0track=NULL;
711 delete trackV0; trackV0=NULL;
712 twoTrackArrayV0->Clear();
713 twoTrackArrayCasc->Clear();
714 if(ioCascade) { delete ioCascade; ioCascade=NULL; }
715 if(vertexCasc) { delete vertexCasc; vertexCasc=NULL; }
716 if(!fInputAOD) {delete v0; v0=NULL;}
718 } // end loop on V0's
721 // If there is less than 2 particles continue
723 AliDebug(1,Form(" Not enough tracks: %d",trkEntries));
727 if(postrack1->Charge()<0 && !fLikeSign) continue;
729 // LOOP ON NEGATIVE TRACKS
730 for(iTrkN1=0; iTrkN1<nSeleTrks; iTrkN1++) {
732 //if(iTrkN1%1==0) AliDebug(1,Form(" 1st loop on neg: track number %d of %d",iTrkN1,nSeleTrks));
733 //if(iTrkN1%1==0) printf(" 1st loop on neg: track number %d of %d\n",iTrkN1,nSeleTrks);
735 if(iTrkN1==iTrkP1) continue;
737 // get track from tracks array
738 negtrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN1);
740 if(negtrack1->Charge()>0 && !fLikeSign) continue;
742 if(!TESTBIT(seleFlags[iTrkN1],kBitDispl)) continue;
745 if(evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
748 if(postrack1->Charge()==negtrack1->Charge()) { // like-sign
749 isLikeSign2Prong=kTRUE;
750 if(!fLikeSign) continue;
751 if(iTrkN1<iTrkP1) continue; // this is needed to avoid double-counting of like-sign
752 } else { // unlike-sign
753 isLikeSign2Prong=kFALSE;
754 if(postrack1->Charge()<0 || negtrack1->Charge()>0) continue; // this is needed to avoid double-counting of unlike-sign
756 if(evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
761 // back to primary vertex
762 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
763 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
764 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
765 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
766 negtrack1->GetPxPyPz(momneg1);
768 // DCA between the two tracks
769 dcap1n1 = postrack1->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
770 if(dcap1n1>dcaMax) { negtrack1=0; continue; }
773 twoTrackArray1->AddAt(postrack1,0);
774 twoTrackArray1->AddAt(negtrack1,1);
775 AliAODVertex *vertexp1n1 = ReconstructSecondaryVertex(twoTrackArray1,dispersion);
777 twoTrackArray1->Clear();
783 if(fD0toKpi || fJPSItoEle || fDstar || fLikeSign) {
785 io2Prong = Make2Prong(twoTrackArray1,event,vertexp1n1,dcap1n1,okD0,okJPSI,okD0fromDstar);
787 if((fD0toKpi && okD0) || (fJPSItoEle && okJPSI) || (isLikeSign2Prong && (okD0 || okJPSI))) {
788 // add the vertex and the decay to the AOD
789 AliAODVertex *v2Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
790 if(!isLikeSign2Prong) {
792 rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
793 rd->SetSecondaryVtx(v2Prong);
794 v2Prong->SetParent(rd);
795 AddRefs(v2Prong,rd,event,twoTrackArray1);
798 rd = new(aodJPSItoEleRef[iJPSItoEle++])AliAODRecoDecayHF2Prong(*io2Prong);
799 rd->SetSecondaryVtx(v2Prong);
800 if(!okD0) v2Prong->SetParent(rd); // it cannot have two mothers ...
801 AddRefs(v2Prong,rd,event,twoTrackArray1);
803 } else { // isLikeSign2Prong
804 rd = new(aodLikeSign2ProngRef[iLikeSign2Prong++])AliAODRecoDecayHF2Prong(*io2Prong);
805 rd->SetSecondaryVtx(v2Prong);
806 v2Prong->SetParent(rd);
807 AddRefs(v2Prong,rd,event,twoTrackArray1);
809 // Set selection bit for PID
810 if(okD0) SetSelectionBitForPID(fCutsD0toKpi,rd,AliRDHFCuts::kD0toKpiPID);
813 if(fDstar && okD0fromDstar && !isLikeSign2Prong) {
814 // write references in io2Prong
816 AddDaughterRefs(vertexp1n1,event,twoTrackArray1);
818 vertexp1n1->AddDaughter(postrack1);
819 vertexp1n1->AddDaughter(negtrack1);
821 io2Prong->SetSecondaryVtx(vertexp1n1);
822 //printf("---> %d %d %d %d %d\n",vertexp1n1->GetNDaughters(),iTrkP1,iTrkN1,postrack1->Charge(),negtrack1->Charge());
823 // create a track from the D0
824 AliNeutralTrackParam *trackD0 = new AliNeutralTrackParam(io2Prong);
826 // LOOP ON TRACKS THAT PASSED THE SOFT PION CUTS
827 for(iTrkSoftPi=0; iTrkSoftPi<nSeleTrks; iTrkSoftPi++) {
829 if(iTrkSoftPi==iTrkP1 || iTrkSoftPi==iTrkN1) continue;
831 if(!TESTBIT(seleFlags[iTrkSoftPi],kBitSoftPi)) continue;
834 if(evtNumber[iTrkP1]==evtNumber[iTrkSoftPi] ||
835 evtNumber[iTrkN1]==evtNumber[iTrkSoftPi] ||
836 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
839 //if(iTrkSoftPi%1==0) AliDebug(1,Form(" 1st loop on pi_s: track number %d of %d",iTrkSoftPi,nSeleTrks));
841 trackD0->PropagateToDCA(fV1,fBzkG,kVeryBig);
842 if(trackD0->GetSigmaY2()<0. || trackD0->GetSigmaZ2()<0.) continue; // this is insipired by the AliITStrackV2::Invariant() checks
844 // get track from tracks array
845 trackPi = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkSoftPi);
846 // trackPi->PropagateToDCA(fV1,fBzkG,kVeryBig);
847 SetParametersAtVertex(trackPi,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkSoftPi));
848 twoTrackArrayCasc->AddAt(trackPi,0);
849 twoTrackArrayCasc->AddAt(trackD0,1);
850 if(!SelectInvMassAndPtDstarD0pi(twoTrackArrayCasc)){
851 twoTrackArrayCasc->Clear();
856 AliAODVertex *vertexCasc = 0;
858 if(fFindVertexForDstar) {
859 // DCA between the two tracks
860 dcaCasc = trackPi->GetDCA(trackD0,fBzkG,xdummy,ydummy);
862 vertexCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
864 // assume Dstar decays at the primary vertex
865 Double_t pos[3],cov[6],chi2perNDF;
867 fV1->GetCovMatrix(cov);
868 chi2perNDF = fV1->GetChi2toNDF();
869 vertexCasc = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,2);
873 twoTrackArrayCasc->Clear();
878 ioCascade = MakeCascade(twoTrackArrayCasc,event,vertexCasc,io2Prong,dcaCasc,okDstar);
880 // add the D0 to the AOD (if not already done)
882 AliAODVertex *v2Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
883 rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
884 rd->SetSecondaryVtx(v2Prong);
885 v2Prong->SetParent(rd);
886 AddRefs(v2Prong,rd,event,twoTrackArray1);
887 okD0=kTRUE; // this is done to add it only once
889 // add the vertex and the cascade to the AOD
890 AliAODVertex *vCasc = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexCasc);
891 rc = new(aodDstarRef[iDstar++])AliAODRecoCascadeHF(*ioCascade);
892 rc->SetSecondaryVtx(vCasc);
893 vCasc->SetParent(rc);
894 if(!fInputAOD) vCasc->AddDaughter(rd); // just to fill ref #0
895 AddRefs(vCasc,rc,event,twoTrackArrayCasc);
896 vCasc->AddDaughter(rd); // add the D0 (in ref #1)
897 // Set selection bit for PID
898 SetSelectionBitForPID(fCutsDStartoKpipi,rc,AliRDHFCuts::kDstarPID);
900 twoTrackArrayCasc->Clear();
902 if(ioCascade) {delete ioCascade; ioCascade=NULL;}
903 delete vertexCasc; vertexCasc=NULL;
904 } // end loop on soft pi tracks
906 if(trackD0) {delete trackD0; trackD0=NULL;}
909 if(io2Prong) {delete io2Prong; io2Prong=NULL;}
912 twoTrackArray1->Clear();
913 if( (!f3Prong && !f4Prong) ||
914 (isLikeSign2Prong && !f3Prong) ) {
921 // 2nd LOOP ON POSITIVE TRACKS
922 for(iTrkP2=iTrkP1+1; iTrkP2<nSeleTrks; iTrkP2++) {
924 if(iTrkP2==iTrkP1 || iTrkP2==iTrkN1) continue;
926 //if(iTrkP2%1==0) AliDebug(1,Form(" 2nd loop on pos: track number %d of %d",iTrkP2,nSeleTrks));
928 // get track from tracks array
929 postrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP2);
931 if(postrack2->Charge()<0) continue;
933 if(!TESTBIT(seleFlags[iTrkP2],kBitDispl)) continue;
935 // Check single tracks cuts specific for 3 prongs
936 if(!TESTBIT(seleFlags[iTrkP2],kBit3Prong)) continue;
937 if(!TESTBIT(seleFlags[iTrkP1],kBit3Prong)) continue;
938 if(!TESTBIT(seleFlags[iTrkN1],kBit3Prong)) continue;
941 if(evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
942 evtNumber[iTrkN1]==evtNumber[iTrkP2] ||
943 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
946 if(isLikeSign2Prong) { // like-sign pair -> have to build only like-sign triplet
947 if(!fLikeSign3prong) continue;
948 if(postrack1->Charge()>0) { // ok: like-sign triplet (+++)
949 isLikeSign3Prong=kTRUE;
953 } else { // normal triplet (+-+)
954 isLikeSign3Prong=kFALSE;
956 if(evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
957 evtNumber[iTrkN1]==evtNumber[iTrkP2] ||
958 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
962 if(fUseKaonPIDfor3Prong){
963 Double_t nsigmatofK= fPidResponse->NumberOfSigmasTOF(negtrack1,AliPID::kKaon);
964 if(nsigmatofK>-990. && (nsigmatofK<-fnSigmaTOFKaonLow || nsigmatofK>fnSigmaTOFKaonHi)) continue;
966 // back to primary vertex
967 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
968 // postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
969 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
970 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
971 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
972 SetParametersAtVertex(postrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP2));
974 //printf("********** %d %d %d\n",postrack1->GetID(),postrack2->GetID(),negtrack1->GetID());
976 dcap2n1 = postrack2->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
977 if(dcap2n1>dcaMax) { postrack2=0; continue; }
978 dcap1p2 = postrack2->GetDCA(postrack1,fBzkG,xdummy,ydummy);
979 if(dcap1p2>dcaMax) { postrack2=0; continue; }
981 // check invariant mass cuts for D+,Ds,Lc
984 if(postrack2->Charge()>0) {
985 threeTrackArray->AddAt(postrack1,0);
986 threeTrackArray->AddAt(negtrack1,1);
987 threeTrackArray->AddAt(postrack2,2);
989 threeTrackArray->AddAt(negtrack1,0);
990 threeTrackArray->AddAt(postrack1,1);
991 threeTrackArray->AddAt(postrack2,2);
993 if(fMassCutBeforeVertexing){
994 postrack2->GetPxPyPz(mompos2);
995 Double_t pxDau[3]={mompos1[0],momneg1[0],mompos2[0]};
996 Double_t pyDau[3]={mompos1[1],momneg1[1],mompos2[1]};
997 Double_t pzDau[3]={mompos1[2],momneg1[2],mompos2[2]};
998 // massCutOK = SelectInvMassAndPt3prong(threeTrackArray);
999 massCutOK = SelectInvMassAndPt3prong(pxDau,pyDau,pzDau);
1003 if(f3Prong && !massCutOK) {
1004 threeTrackArray->Clear();
1012 twoTrackArray2->AddAt(postrack2,0);
1013 twoTrackArray2->AddAt(negtrack1,1);
1014 AliAODVertex *vertexp2n1 = ReconstructSecondaryVertex(twoTrackArray2,dispersion);
1016 twoTrackArray2->Clear();
1021 // 3 prong candidates
1022 if(f3Prong && massCutOK) {
1024 AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1025 io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,vertexp2n1,dcap1n1,dcap2n1,dcap1p2,ok3Prong);
1027 AliAODVertex *v3Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
1028 if(!isLikeSign3Prong) {
1029 rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1030 rd->SetSecondaryVtx(v3Prong);
1031 v3Prong->SetParent(rd);
1032 AddRefs(v3Prong,rd,event,threeTrackArray);
1033 } else { // isLikeSign3Prong
1034 if(fLikeSign3prong){
1035 rd = new(aodLikeSign3ProngRef[iLikeSign3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1036 rd->SetSecondaryVtx(v3Prong);
1037 v3Prong->SetParent(rd);
1038 AddRefs(v3Prong,rd,event,threeTrackArray);
1041 // Set selection bit for PID
1042 SetSelectionBitForPID(fCutsDplustoKpipi,rd,AliRDHFCuts::kDplusPID);
1043 SetSelectionBitForPID(fCutsDstoKKpi,rd,AliRDHFCuts::kDsPID);
1044 SetSelectionBitForPID(fCutsLctopKpi,rd,AliRDHFCuts::kLcPID);
1046 if(io3Prong) {delete io3Prong; io3Prong=NULL;}
1047 if(secVert3PrAOD) {delete secVert3PrAOD; secVert3PrAOD=NULL;}
1050 // 4 prong candidates
1052 // don't make 4 prong with like-sign pairs and triplets
1053 && !isLikeSign2Prong && !isLikeSign3Prong
1054 // track-to-track dca cuts already now
1055 && dcap1n1 < fCutsD0toKpipipi->GetDCACut()
1056 && dcap2n1 < fCutsD0toKpipipi->GetDCACut()) {
1058 // back to primary vertex
1059 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1060 // postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1061 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1062 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1063 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1064 SetParametersAtVertex(postrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP2));
1066 // Vertexing for these 3 (can be taken from above?)
1067 threeTrackArray->AddAt(postrack1,0);
1068 threeTrackArray->AddAt(negtrack1,1);
1069 threeTrackArray->AddAt(postrack2,2);
1070 AliAODVertex* vertexp1n1p2 = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1072 // 3rd LOOP ON NEGATIVE TRACKS (for 4 prong)
1073 for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
1075 if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
1077 //if(iTrkN2%1==0) AliDebug(1,Form(" 3rd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));
1079 // get track from tracks array
1080 negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
1082 if(negtrack2->Charge()>0) continue;
1084 if(!TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
1086 if(evtNumber[iTrkP1]==evtNumber[iTrkN2] ||
1087 evtNumber[iTrkN1]==evtNumber[iTrkN2] ||
1088 evtNumber[iTrkP2]==evtNumber[iTrkN2] ||
1089 evtNumber[iTrkP1]==evtNumber[iTrkN1] ||
1090 evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
1091 evtNumber[iTrkN1]==evtNumber[iTrkP2]) continue;
1094 // back to primary vertex
1095 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1096 // postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1097 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1098 // negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1099 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1100 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1101 SetParametersAtVertex(postrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP2));
1102 SetParametersAtVertex(negtrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN2));
1104 dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1105 if(dcap1n2 > fCutsD0toKpipipi->GetDCACut()) { negtrack2=0; continue; }
1106 dcap2n2 = postrack2->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1107 if(dcap2n2 > fCutsD0toKpipipi->GetDCACut()) { negtrack2=0; continue; }
1110 fourTrackArray->AddAt(postrack1,0);
1111 fourTrackArray->AddAt(negtrack1,1);
1112 fourTrackArray->AddAt(postrack2,2);
1113 fourTrackArray->AddAt(negtrack2,3);
1115 // check invariant mass cuts for D0
1117 if(fMassCutBeforeVertexing)
1118 massCutOK = SelectInvMassAndPt4prong(fourTrackArray);
1121 fourTrackArray->Clear();
1127 AliAODVertex* secVert4PrAOD = ReconstructSecondaryVertex(fourTrackArray,dispersion);
1128 io4Prong = Make4Prong(fourTrackArray,event,secVert4PrAOD,vertexp1n1,vertexp1n1p2,dcap1n1,dcap1n2,dcap2n1,dcap2n2,ok4Prong);
1130 AliAODVertex *v4Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert4PrAOD);
1131 rd = new(aodCharm4ProngRef[i4Prong++])AliAODRecoDecayHF4Prong(*io4Prong);
1132 rd->SetSecondaryVtx(v4Prong);
1133 v4Prong->SetParent(rd);
1134 AddRefs(v4Prong,rd,event,fourTrackArray);
1137 if(io4Prong) {delete io4Prong; io4Prong=NULL;}
1138 if(secVert4PrAOD) {delete secVert4PrAOD; secVert4PrAOD=NULL;}
1139 fourTrackArray->Clear();
1142 } // end loop on negative tracks
1144 threeTrackArray->Clear();
1145 delete vertexp1n1p2;
1152 } // end 2nd loop on positive tracks
1154 twoTrackArray2->Clear();
1156 // 2nd LOOP ON NEGATIVE TRACKS (for 3 prong -+-)
1157 for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
1159 if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
1161 //if(iTrkN2%1==0) AliDebug(1,Form(" 2nd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));
1163 // get track from tracks array
1164 negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
1166 if(negtrack2->Charge()>0) continue;
1168 if(!TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
1170 // Check single tracks cuts specific for 3 prongs
1171 if(!TESTBIT(seleFlags[iTrkN2],kBit3Prong)) continue;
1172 if(!TESTBIT(seleFlags[iTrkP1],kBit3Prong)) continue;
1173 if(!TESTBIT(seleFlags[iTrkN1],kBit3Prong)) continue;
1176 if(evtNumber[iTrkP1]==evtNumber[iTrkN2] ||
1177 evtNumber[iTrkN1]==evtNumber[iTrkN2] ||
1178 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
1181 if(isLikeSign2Prong) { // like-sign pair -> have to build only like-sign triplet
1182 if(!fLikeSign3prong) continue;
1183 if(postrack1->Charge()<0) { // ok: like-sign triplet (---)
1184 isLikeSign3Prong=kTRUE;
1188 } else { // normal triplet (-+-)
1189 isLikeSign3Prong=kFALSE;
1192 if(fUseKaonPIDfor3Prong){
1193 Double_t nsigmatofK= fPidResponse->NumberOfSigmasTOF(postrack1,AliPID::kKaon);
1194 if(nsigmatofK>-990. && (nsigmatofK<-fnSigmaTOFKaonLow || nsigmatofK>fnSigmaTOFKaonHi)) continue;
1197 // back to primary vertex
1198 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1199 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1200 // negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1201 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1202 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1203 SetParametersAtVertex(negtrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN2));
1204 //printf("********** %d %d %d\n",postrack1->GetID(),negtrack1->GetID(),negtrack2->GetID());
1206 dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1207 if(dcap1n2>dcaMax) { negtrack2=0; continue; }
1208 dcan1n2 = negtrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1209 if(dcan1n2>dcaMax) { negtrack2=0; continue; }
1211 threeTrackArray->AddAt(negtrack1,0);
1212 threeTrackArray->AddAt(postrack1,1);
1213 threeTrackArray->AddAt(negtrack2,2);
1215 // check invariant mass cuts for D+,Ds,Lc
1217 if(fMassCutBeforeVertexing && f3Prong){
1218 negtrack2->GetPxPyPz(momneg2);
1219 Double_t pxDau[3]={momneg1[0],mompos1[0],momneg2[0]};
1220 Double_t pyDau[3]={momneg1[1],mompos1[1],momneg2[1]};
1221 Double_t pzDau[3]={momneg1[2],mompos1[2],momneg2[2]};
1222 // massCutOK = SelectInvMassAndPt3prong(threeTrackArray);
1223 massCutOK = SelectInvMassAndPt3prong(pxDau,pyDau,pzDau);
1226 threeTrackArray->Clear();
1232 twoTrackArray2->AddAt(postrack1,0);
1233 twoTrackArray2->AddAt(negtrack2,1);
1235 AliAODVertex *vertexp1n2 = ReconstructSecondaryVertex(twoTrackArray2,dispersion);
1237 twoTrackArray2->Clear();
1243 AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1244 io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,vertexp1n2,dcap1n1,dcap1n2,dcan1n2,ok3Prong);
1246 AliAODVertex *v3Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
1247 if(!isLikeSign3Prong) {
1248 rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1249 rd->SetSecondaryVtx(v3Prong);
1250 v3Prong->SetParent(rd);
1251 AddRefs(v3Prong,rd,event,threeTrackArray);
1252 } else { // isLikeSign3Prong
1253 if(fLikeSign3prong){
1254 rd = new(aodLikeSign3ProngRef[iLikeSign3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1255 rd->SetSecondaryVtx(v3Prong);
1256 v3Prong->SetParent(rd);
1257 AddRefs(v3Prong,rd,event,threeTrackArray);
1260 // Set selection bit for PID
1261 SetSelectionBitForPID(fCutsDplustoKpipi,rd,AliRDHFCuts::kDplusPID);
1262 SetSelectionBitForPID(fCutsDstoKKpi,rd,AliRDHFCuts::kDsPID);
1263 SetSelectionBitForPID(fCutsLctopKpi,rd,AliRDHFCuts::kLcPID);
1265 if(io3Prong) {delete io3Prong; io3Prong=NULL;}
1266 if(secVert3PrAOD) {delete secVert3PrAOD; secVert3PrAOD=NULL;}
1268 threeTrackArray->Clear();
1272 } // end 2nd loop on negative tracks
1274 twoTrackArray2->Clear();
1278 } // end 1st loop on negative tracks
1281 } // end 1st loop on positive tracks
1284 AliDebug(1,Form(" Total HF vertices in event = %d;",
1285 (Int_t)aodVerticesHFTClArr->GetEntriesFast()));
1287 AliDebug(1,Form(" D0->Kpi in event = %d;",
1288 (Int_t)aodD0toKpiTClArr->GetEntriesFast()));
1291 AliDebug(1,Form(" JPSI->ee in event = %d;",
1292 (Int_t)aodJPSItoEleTClArr->GetEntriesFast()));
1295 AliDebug(1,Form(" Charm->3Prong in event = %d;",
1296 (Int_t)aodCharm3ProngTClArr->GetEntriesFast()));
1299 AliDebug(1,Form(" Charm->4Prong in event = %d;\n",
1300 (Int_t)aodCharm4ProngTClArr->GetEntriesFast()));
1303 AliDebug(1,Form(" D*->D0pi in event = %d;\n",
1304 (Int_t)aodDstarTClArr->GetEntriesFast()));
1307 AliDebug(1,Form(" cascades -> v0 + track in event = %d;\n",
1308 (Int_t)aodCascadesTClArr->GetEntriesFast()));
1311 AliDebug(1,Form(" Like-sign 2Prong in event = %d;\n",
1312 (Int_t)aodLikeSign2ProngTClArr->GetEntriesFast()));
1314 if(fLikeSign3prong && f3Prong) {
1315 AliDebug(1,Form(" Like-sign 3Prong in event = %d;\n",
1316 (Int_t)aodLikeSign3ProngTClArr->GetEntriesFast()));
1320 twoTrackArray1->Delete(); delete twoTrackArray1;
1321 twoTrackArray2->Delete(); delete twoTrackArray2;
1322 twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
1323 twoTrackArrayV0->Delete(); delete twoTrackArrayV0;
1324 threeTrackArray->Clear();
1325 threeTrackArray->Delete(); delete threeTrackArray;
1326 fourTrackArray->Delete(); delete fourTrackArray;
1327 delete [] seleFlags; seleFlags=NULL;
1328 if(evtNumber) {delete [] evtNumber; evtNumber=NULL;}
1329 tracksAtVertex.Delete();
1332 seleTrksArray.Delete();
1333 if(fAODMap) { delete [] fAODMap; fAODMap=NULL; }
1337 //printf("Trks: total %d sele %d\n",fnTrksTotal,fnSeleTrksTotal);
1341 //----------------------------------------------------------------------------
1342 void AliAnalysisVertexingHF::AddRefs(AliAODVertex *v,AliAODRecoDecayHF *rd,
1343 const AliVEvent *event,
1344 const TObjArray *trkArray) const
1346 // Add the AOD tracks as daughters of the vertex (TRef)
1347 // Also add the references to the primary vertex and to the cuts
1348 //AliCodeTimerAuto("",0);
1351 AddDaughterRefs(v,event,trkArray);
1352 rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1356 rd->SetListOfCutsRef((TList*)fListOfCuts);
1357 //fListOfCuts->Print();
1358 cout<<fListOfCuts<<endl;
1359 TList *l=(TList*)rd->GetListOfCuts();
1361 if(l) {l->Print(); }else{printf("error\n");}
1366 //----------------------------------------------------------------------------
1367 void AliAnalysisVertexingHF::AddDaughterRefs(AliAODVertex *v,
1368 const AliVEvent *event,
1369 const TObjArray *trkArray) const
1371 // Add the AOD tracks as daughters of the vertex (TRef)
1372 //AliCodeTimerAuto("",0);
1374 Int_t nDg = v->GetNDaughters();
1376 if(nDg) dg = v->GetDaughter(0);
1378 if(dg) return; // daughters already added
1380 Int_t nTrks = trkArray->GetEntriesFast();
1382 AliExternalTrackParam *track = 0;
1383 AliAODTrack *aodTrack = 0;
1386 for(Int_t i=0; i<nTrks; i++) {
1387 track = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
1388 id = (Int_t)track->GetID();
1389 //printf("---> %d\n",id);
1390 if(id<0) continue; // this track is a AliAODRecoDecay
1391 aodTrack = (AliAODTrack*)event->GetTrack(fAODMap[id]);
1392 v->AddDaughter(aodTrack);
1397 //---------------------------------------------------------------------------
1398 void AliAnalysisVertexingHF::FixReferences(AliAODEvent *aod)
1400 // Checks that the references to the daughter tracks are properly
1401 // assigned and reassigns them if needed
1403 //AliCodeTimerAuto("",0);
1406 TClonesArray *inputArray=(TClonesArray*)aod->GetList()->FindObject("VerticesHF");
1407 if(!inputArray) return;
1409 AliAODTrack *track = 0;
1410 AliAODVertex *vertex = 0;
1412 Bool_t needtofix=kFALSE;
1413 for(Int_t iv=0; iv<inputArray->GetEntriesFast(); iv++) {
1414 vertex = (AliAODVertex*)inputArray->UncheckedAt(iv);
1415 for(Int_t id=0; id<vertex->GetNDaughters(); id++) {
1416 track = (AliAODTrack*)vertex->GetDaughter(id);
1417 if(!track->GetStatus()) needtofix=kTRUE;
1419 if(needtofix) break;
1422 if(!needtofix) return;
1425 printf("Fixing references\n");
1427 fAODMapSize = 100000;
1428 fAODMap = new Int_t[fAODMapSize];
1429 memset(fAODMap,0,sizeof(Int_t)*fAODMapSize);
1431 for(Int_t i=0; i<aod->GetNumberOfTracks(); i++) {
1432 track = aod->GetTrack(i);
1434 // skip pure ITS SA tracks
1435 if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
1437 // skip tracks without ITS
1438 if(!(track->GetStatus()&AliESDtrack::kITSin)) continue;
1440 // TEMPORARY: check that the cov matrix is there
1441 Double_t covtest[21];
1442 if(!track->GetCovarianceXYZPxPyPz(covtest)) continue;
1445 Int_t ind = (Int_t)track->GetID();
1446 if (ind>-1 && ind < fAODMapSize) fAODMap[ind] = i;
1450 Int_t ids[4]={-1,-1,-1,-1};
1451 for(Int_t iv=0; iv<inputArray->GetEntriesFast(); iv++) {
1452 Bool_t cascade=kFALSE;
1453 vertex = (AliAODVertex*)inputArray->UncheckedAt(iv);
1455 Int_t nDgs = vertex->GetNDaughters();
1456 for(id=0; id<nDgs; id++) {
1457 track = (AliAODTrack*)vertex->GetDaughter(id);
1458 if(track->Charge()==0) {cascade=kTRUE; continue;} // cascade
1459 ids[id]=(Int_t)track->GetID();
1460 vertex->RemoveDaughter(track);
1462 if(cascade) continue;
1463 for(id=0; id<nDgs; id++) {
1464 if (ids[id]>-1 && ids[id] < fAODMapSize) {
1465 track = aod->GetTrack(fAODMap[ids[id]]);
1466 vertex->AddDaughter(track);
1474 //----------------------------------------------------------------------------
1475 AliAODRecoCascadeHF* AliAnalysisVertexingHF::MakeCascade(
1476 TObjArray *twoTrackArray,AliVEvent *event,
1477 AliAODVertex *secVert,
1478 AliAODRecoDecayHF2Prong *rd2Prong,
1482 // Make the cascade as a 2Prong decay and check if it passes Dstar
1483 // reconstruction cuts
1484 //AliCodeTimerAuto("",0);
1488 Bool_t dummy1,dummy2,dummy3;
1490 // We use Make2Prong to construct the AliAODRecoCascadeHF
1491 // (which inherits from AliAODRecoDecayHF2Prong)
1492 AliAODRecoCascadeHF *theCascade =
1493 (AliAODRecoCascadeHF*)Make2Prong(twoTrackArray,event,secVert,dca,
1494 dummy1,dummy2,dummy3);
1495 if(!theCascade) return 0x0;
1498 AliESDtrack *trackPi = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
1499 theCascade->SetCharge(trackPi->Charge());
1501 //--- selection cuts
1503 AliAODRecoCascadeHF *tmpCascade = new AliAODRecoCascadeHF(*theCascade);
1505 Int_t idSoftPi=(Int_t)trackPi->GetID();
1506 if (idSoftPi > -1 && idSoftPi < fAODMapSize) {
1507 AliAODTrack* trackPiAOD=(AliAODTrack*)event->GetTrack(fAODMap[idSoftPi]);
1508 tmpCascade->GetSecondaryVtx()->AddDaughter(trackPiAOD);
1511 tmpCascade->GetSecondaryVtx()->AddDaughter(trackPi);
1513 tmpCascade->GetSecondaryVtx()->AddDaughter(rd2Prong);
1515 AliAODVertex *primVertexAOD=0;
1516 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
1517 // take event primary vertex
1518 primVertexAOD = PrimaryVertex();
1519 tmpCascade->SetOwnPrimaryVtx(primVertexAOD);
1520 rd2Prong->SetOwnPrimaryVtx(primVertexAOD);
1524 okDstar = (Bool_t)fCutsDStartoKpipi->IsSelected(tmpCascade,AliRDHFCuts::kCandidate);
1525 if(okDstar) theCascade->SetSelectionBit(AliRDHFCuts::kDstarCuts);
1527 tmpCascade->GetSecondaryVtx()->RemoveDaughters();
1528 tmpCascade->UnsetOwnPrimaryVtx();
1529 delete tmpCascade; tmpCascade=NULL;
1530 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1531 rd2Prong->UnsetOwnPrimaryVtx();
1533 if(primVertexAOD) {delete primVertexAOD; primVertexAOD=NULL;}
1541 //----------------------------------------------------------------------------
1542 AliAODRecoCascadeHF* AliAnalysisVertexingHF::MakeCascade(
1543 TObjArray *twoTrackArray,AliVEvent *event,
1544 AliAODVertex *secVert,
1550 // Make the cascade as a 2Prong decay and check if it passes
1551 // cascades reconstruction cuts
1552 //AliCodeTimerAuto("",0);
1554 // AliDebug(2,Form(" building the cascade"));
1556 Bool_t dummy1,dummy2,dummy3;
1558 // We use Make2Prong to construct the AliAODRecoCascadeHF
1559 // (which inherits from AliAODRecoDecayHF2Prong)
1560 AliAODRecoCascadeHF *theCascade =
1561 (AliAODRecoCascadeHF*)Make2Prong(twoTrackArray,event,secVert,dca,
1562 dummy1,dummy2,dummy3);
1563 if(!theCascade) return 0x0;
1565 // bachelor track and charge
1566 AliESDtrack *trackBachelor = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
1567 theCascade->SetCharge(trackBachelor->Charge());
1569 //--- selection cuts
1572 AliAODRecoCascadeHF *tmpCascade = new AliAODRecoCascadeHF(*theCascade);
1574 Int_t idBachelor=(Int_t)trackBachelor->GetID();
1575 if (idBachelor > -1 && idBachelor < fAODMapSize) {
1576 AliAODTrack* trackBachelorAOD=(AliAODTrack*)event->GetTrack(fAODMap[idBachelor]);
1577 tmpCascade->GetSecondaryVtx()->AddDaughter(trackBachelorAOD);
1580 tmpCascade->GetSecondaryVtx()->AddDaughter(trackBachelor);
1582 tmpCascade->GetSecondaryVtx()->AddDaughter(v0);
1584 AliAODVertex *primVertexAOD=0;
1585 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
1586 // take event primary vertex
1587 primVertexAOD = PrimaryVertex();
1588 if(!primVertexAOD) primVertexAOD = (AliAODVertex*)event->GetPrimaryVertex();
1589 tmpCascade->SetOwnPrimaryVtx(primVertexAOD);
1593 if(fCascades && fInputAOD){
1594 okCascades = (Bool_t)fCutsLctoV0->IsSelected(tmpCascade,AliRDHFCuts::kCandidate);
1597 //AliDebug(2,Form("The cascade is contructed from ESDs, no cuts are applied"));
1599 }// no cuts implemented from ESDs
1600 tmpCascade->GetSecondaryVtx()->RemoveDaughters();
1601 tmpCascade->UnsetOwnPrimaryVtx();
1602 delete tmpCascade; tmpCascade=NULL;
1603 if(primVertexAOD) {delete primVertexAOD; primVertexAOD=NULL;}
1609 //-----------------------------------------------------------------------------
1610 AliAODRecoDecayHF2Prong *AliAnalysisVertexingHF::Make2Prong(
1611 TObjArray *twoTrackArray,AliVEvent *event,
1612 AliAODVertex *secVert,Double_t dca,
1613 Bool_t &okD0,Bool_t &okJPSI,
1614 Bool_t &okD0fromDstar)
1616 // Make 2Prong candidates and check if they pass D0toKpi or BtoJPSI
1617 // reconstruction cuts
1618 // G.E.Bruno (J/psi), A.Dainese (D0->Kpi)
1619 //AliCodeTimerAuto("",0);
1621 okD0=kFALSE; okJPSI=kFALSE; okD0fromDstar=kFALSE;
1623 Double_t px[2],py[2],pz[2],d0[2],d0err[2];
1624 AliESDtrack *postrack = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
1625 AliESDtrack *negtrack = (AliESDtrack*)twoTrackArray->UncheckedAt(1);
1627 // propagate tracks to secondary vertex, to compute inv. mass
1628 postrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
1629 negtrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
1631 Double_t momentum[3];
1632 postrack->GetPxPyPz(momentum);
1633 px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
1634 negtrack->GetPxPyPz(momentum);
1635 px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
1638 // invariant mass cut (try to improve coding here..)
1639 Bool_t okMassCut=kFALSE;
1640 if(!okMassCut && fD0toKpi) if(SelectInvMassAndPtD0Kpi(px,py,pz)) okMassCut=kTRUE;
1641 if(!okMassCut && fJPSItoEle) if(SelectInvMassAndPtJpsiee(px,py,pz)) okMassCut=kTRUE;
1642 if(!okMassCut && fDstar) if(SelectInvMassAndPtDstarD0pi(px,py,pz)) okMassCut=kTRUE;
1643 if(!okMassCut && fCascades) if(SelectInvMassAndPtCascade(px,py,pz)) okMassCut=kTRUE;
1645 //AliDebug(2," candidate didn't pass mass cut");
1648 // primary vertex to be used by this candidate
1649 AliAODVertex *primVertexAOD = PrimaryVertex(twoTrackArray,event);
1650 if(!primVertexAOD) return 0x0;
1653 Double_t d0z0[2],covd0z0[3];
1654 postrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1656 d0err[0] = TMath::Sqrt(covd0z0[0]);
1657 negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1659 d0err[1] = TMath::Sqrt(covd0z0[0]);
1661 // create the object AliAODRecoDecayHF2Prong
1662 AliAODRecoDecayHF2Prong *the2Prong = new AliAODRecoDecayHF2Prong(secVert,px,py,pz,d0,d0err,dca);
1663 the2Prong->SetOwnPrimaryVtx(primVertexAOD);
1664 UShort_t id[2]={(UShort_t)postrack->GetID(),(UShort_t)negtrack->GetID()};
1665 the2Prong->SetProngIDs(2,id);
1666 delete primVertexAOD; primVertexAOD=NULL;
1669 if(postrack->Charge()!=0 && negtrack->Charge()!=0) { // don't apply these cuts if it's a Dstar
1671 // Add daughter references already here
1672 if(fInputAOD) AddDaughterRefs(secVert,(AliAODEvent*)event,twoTrackArray);
1676 okD0 = (Bool_t)fCutsD0toKpi->IsSelected(the2Prong,AliRDHFCuts::kCandidate,(AliAODEvent*)event);
1677 if(okD0) the2Prong->SetSelectionBit(AliRDHFCuts::kD0toKpiCuts);
1679 //if(fDebug && fD0toKpi) printf(" %d\n",(Int_t)okD0);
1680 // select J/psi from B
1682 okJPSI = (Bool_t)fCutsJpsitoee->IsSelected(the2Prong,AliRDHFCuts::kCandidate);
1684 //if(fDebug && fJPSItoEle) printf(" %d\n",(Int_t)okJPSI);
1685 // select D0->Kpi from Dstar
1687 okD0fromDstar = (Bool_t)fCutsDStartoKpipi->IsD0FromDStarSelected(the2Prong->Pt(),the2Prong,AliRDHFCuts::kCandidate);
1688 if(okD0fromDstar) the2Prong->SetSelectionBit(AliRDHFCuts::kD0fromDstarCuts);
1690 //if(fDebug && fDstar) printf(" %d\n",(Int_t)okD0fromDstar);
1694 // remove the primary vertex (was used only for selection)
1695 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1696 the2Prong->UnsetOwnPrimaryVtx();
1699 // get PID info from ESD
1700 Double_t esdpid0[5]={0.,0.,0.,0.,0.};
1701 if(postrack->GetStatus()&AliESDtrack::kESDpid) postrack->GetESDpid(esdpid0);
1702 Double_t esdpid1[5]={0.,0.,0.,0.,0.};
1703 if(negtrack->GetStatus()&AliESDtrack::kESDpid) negtrack->GetESDpid(esdpid1);
1704 Double_t esdpid[10];
1705 for(Int_t i=0;i<5;i++) {
1706 esdpid[i] = esdpid0[i];
1707 esdpid[5+i] = esdpid1[i];
1709 the2Prong->SetPID(2,esdpid);
1713 //----------------------------------------------------------------------------
1714 AliAODRecoDecayHF3Prong* AliAnalysisVertexingHF::Make3Prong(
1715 TObjArray *threeTrackArray,AliVEvent *event,
1716 AliAODVertex *secVert,Double_t dispersion,
1717 const AliAODVertex *vertexp1n1,const AliAODVertex *vertexp2n1,
1718 Double_t dcap1n1,Double_t dcap2n1,Double_t dcap1p2,
1721 // Make 3Prong candidates and check if they pass Dplus or Ds or Lambdac
1722 // reconstruction cuts
1725 //AliCodeTimerAuto("",0);
1728 if(!secVert || !vertexp1n1 || !vertexp2n1) return 0x0;
1730 Double_t px[3],py[3],pz[3],d0[3],d0err[3];
1731 Double_t momentum[3];
1734 AliESDtrack *postrack1 = (AliESDtrack*)threeTrackArray->UncheckedAt(0);
1735 AliESDtrack *negtrack = (AliESDtrack*)threeTrackArray->UncheckedAt(1);
1736 AliESDtrack *postrack2 = (AliESDtrack*)threeTrackArray->UncheckedAt(2);
1738 postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
1739 negtrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
1740 postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
1741 postrack1->GetPxPyPz(momentum);
1742 px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
1743 negtrack->GetPxPyPz(momentum);
1744 px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
1745 postrack2->GetPxPyPz(momentum);
1746 px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2];
1748 // invariant mass cut for D+, Ds, Lc
1749 Bool_t okMassCut=kFALSE;
1750 if(fMassCutBeforeVertexing) okMassCut=kTRUE; // mass cut already done and passed
1751 if(!okMassCut && f3Prong) if(SelectInvMassAndPt3prong(px,py,pz)) okMassCut=kTRUE;
1753 //AliDebug(2," candidate didn't pass mass cut");
1757 // primary vertex to be used by this candidate
1758 AliAODVertex *primVertexAOD = PrimaryVertex(threeTrackArray,event);
1759 if(!primVertexAOD) return 0x0;
1761 Double_t d0z0[2],covd0z0[3];
1762 postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1764 d0err[0] = TMath::Sqrt(covd0z0[0]);
1765 negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1767 d0err[1] = TMath::Sqrt(covd0z0[0]);
1768 postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1770 d0err[2] = TMath::Sqrt(covd0z0[0]);
1773 // create the object AliAODRecoDecayHF3Prong
1774 Double_t pos[3]; primVertexAOD->GetXYZ(pos);
1775 Double_t dca[3]={dcap1n1,dcap2n1,dcap1p2};
1776 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]));
1777 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]));
1778 Short_t charge=(Short_t)(postrack1->Charge()+postrack2->Charge()+negtrack->Charge());
1779 AliAODRecoDecayHF3Prong *the3Prong = new AliAODRecoDecayHF3Prong(secVert,px,py,pz,d0,d0err,dca,dispersion,dist12,dist23,charge);
1780 the3Prong->SetOwnPrimaryVtx(primVertexAOD);
1781 UShort_t id[3]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack->GetID(),(UShort_t)postrack2->GetID()};
1782 the3Prong->SetProngIDs(3,id);
1784 delete primVertexAOD; primVertexAOD=NULL;
1786 // Add daughter references already here
1787 if(fInputAOD) AddDaughterRefs(secVert,(AliAODEvent*)event,threeTrackArray);
1789 // select D+->Kpipi, Ds->KKpi, Lc->pKpi
1793 if(fOKInvMassDplus && fCutsDplustoKpipi->IsSelected(the3Prong,AliRDHFCuts::kCandidate,(AliAODEvent*)event)) {
1795 the3Prong->SetSelectionBit(AliRDHFCuts::kDplusCuts);
1797 if(fOKInvMassDs && fCutsDstoKKpi->IsSelected(the3Prong,AliRDHFCuts::kCandidate,(AliAODEvent*)event)) {
1799 the3Prong->SetSelectionBit(AliRDHFCuts::kDsCuts);
1801 if(fOKInvMassLc && fCutsLctopKpi->IsSelected(the3Prong,AliRDHFCuts::kCandidate,(AliAODEvent*)event)) {
1803 the3Prong->SetSelectionBit(AliRDHFCuts::kLcCuts);
1806 //if(fDebug) printf("ok3Prong: %d\n",(Int_t)ok3Prong);
1808 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1809 the3Prong->UnsetOwnPrimaryVtx();
1812 // get PID info from ESD
1813 Double_t esdpid0[5]={0.,0.,0.,0.,0.};
1814 if(postrack1->GetStatus()&AliESDtrack::kESDpid) postrack1->GetESDpid(esdpid0);
1815 Double_t esdpid1[5]={0.,0.,0.,0.,0.};
1816 if(negtrack->GetStatus()&AliESDtrack::kESDpid) negtrack->GetESDpid(esdpid1);
1817 Double_t esdpid2[5]={0.,0.,0.,0.,0.};
1818 if(postrack2->GetStatus()&AliESDtrack::kESDpid) postrack2->GetESDpid(esdpid2);
1820 Double_t esdpid[15];
1821 for(Int_t i=0;i<5;i++) {
1822 esdpid[i] = esdpid0[i];
1823 esdpid[5+i] = esdpid1[i];
1824 esdpid[10+i] = esdpid2[i];
1826 the3Prong->SetPID(3,esdpid);
1830 //----------------------------------------------------------------------------
1831 AliAODRecoDecayHF4Prong* AliAnalysisVertexingHF::Make4Prong(
1832 TObjArray *fourTrackArray,AliVEvent *event,
1833 AliAODVertex *secVert,
1834 const AliAODVertex *vertexp1n1,
1835 const AliAODVertex *vertexp1n1p2,
1836 Double_t dcap1n1,Double_t dcap1n2,
1837 Double_t dcap2n1,Double_t dcap2n2,
1840 // Make 4Prong candidates and check if they pass D0toKpipipi
1841 // reconstruction cuts
1842 // G.E.Bruno, R.Romita
1843 //AliCodeTimerAuto("",0);
1846 if(!secVert || !vertexp1n1 || !vertexp1n1p2) return 0x0;
1848 Double_t px[4],py[4],pz[4],d0[4],d0err[4];//d0z[3];
1850 AliESDtrack *postrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(0);
1851 AliESDtrack *negtrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(1);
1852 AliESDtrack *postrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(2);
1853 AliESDtrack *negtrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(3);
1855 postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
1856 negtrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
1857 postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
1858 negtrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
1860 Double_t momentum[3];
1861 postrack1->GetPxPyPz(momentum);
1862 px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
1863 negtrack1->GetPxPyPz(momentum);
1864 px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
1865 postrack2->GetPxPyPz(momentum);
1866 px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2];
1867 negtrack2->GetPxPyPz(momentum);
1868 px[3] = momentum[0]; py[3] = momentum[1]; pz[3] = momentum[2];
1870 // invariant mass cut for rho or D0 (try to improve coding here..)
1871 Bool_t okMassCut=kFALSE;
1872 if(fMassCutBeforeVertexing) okMassCut=kTRUE; // mass cut already done and passed
1873 if(!okMassCut && !(fCutsD0toKpipipi->GetUsePID())) { //no PID, to be implemented with PID
1874 if(SelectInvMassAndPt4prong(px,py,pz)) okMassCut=kTRUE;
1877 //if(fDebug) printf(" candidate didn't pass mass cut\n");
1878 //printf(" candidate didn't pass mass cut\n");
1882 // primary vertex to be used by this candidate
1883 AliAODVertex *primVertexAOD = PrimaryVertex(fourTrackArray,event);
1884 if(!primVertexAOD) return 0x0;
1886 Double_t d0z0[2],covd0z0[3];
1887 postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1889 d0err[0] = TMath::Sqrt(covd0z0[0]);
1890 negtrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1892 d0err[1] = TMath::Sqrt(covd0z0[0]);
1893 postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1895 d0err[2] = TMath::Sqrt(covd0z0[0]);
1896 negtrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1898 d0err[3] = TMath::Sqrt(covd0z0[0]);
1901 // create the object AliAODRecoDecayHF4Prong
1902 Double_t pos[3]; primVertexAOD->GetXYZ(pos);
1903 Double_t dca[6]={dcap1n1,0.,dcap1n2,dcap2n1,0.,dcap2n2};
1904 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]));
1905 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]));
1906 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]));
1908 AliAODRecoDecayHF4Prong *the4Prong = new AliAODRecoDecayHF4Prong(secVert,px,py,pz,d0,d0err,dca,dist12,dist3,dist4,charge);
1909 the4Prong->SetOwnPrimaryVtx(primVertexAOD);
1910 UShort_t id[4]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack1->GetID(),(UShort_t)postrack2->GetID(),(UShort_t)negtrack2->GetID()};
1911 the4Prong->SetProngIDs(4,id);
1913 delete primVertexAOD; primVertexAOD=NULL;
1915 ok4Prong=(Bool_t)fCutsD0toKpipipi->IsSelected(the4Prong,AliRDHFCuts::kCandidate);
1918 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1919 the4Prong->UnsetOwnPrimaryVtx();
1923 // get PID info from ESD
1924 Double_t esdpid0[5]={0.,0.,0.,0.,0.};
1925 if(postrack1->GetStatus()&AliESDtrack::kESDpid) postrack1->GetESDpid(esdpid0);
1926 Double_t esdpid1[5]={0.,0.,0.,0.,0.};
1927 if(negtrack1->GetStatus()&AliESDtrack::kESDpid) negtrack1->GetESDpid(esdpid1);
1928 Double_t esdpid2[5]={0.,0.,0.,0.,0.};
1929 if(postrack2->GetStatus()&AliESDtrack::kESDpid) postrack2->GetESDpid(esdpid2);
1930 Double_t esdpid3[5]={0.,0.,0.,0.,0.};
1931 if(negtrack2->GetStatus()&AliESDtrack::kESDpid) negtrack2->GetESDpid(esdpid3);
1933 Double_t esdpid[20];
1934 for(Int_t i=0;i<5;i++) {
1935 esdpid[i] = esdpid0[i];
1936 esdpid[5+i] = esdpid1[i];
1937 esdpid[10+i] = esdpid2[i];
1938 esdpid[15+i] = esdpid3[i];
1940 the4Prong->SetPID(4,esdpid);
1944 //-----------------------------------------------------------------------------
1945 AliAODVertex* AliAnalysisVertexingHF::PrimaryVertex(const TObjArray *trkArray,
1946 AliVEvent *event) const
1948 // Returns primary vertex to be used for this candidate
1949 //AliCodeTimerAuto("",0);
1951 AliESDVertex *vertexESD = 0;
1952 AliAODVertex *vertexAOD = 0;
1955 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
1956 // primary vertex from the input event
1958 vertexESD = new AliESDVertex(*fV1);
1961 // primary vertex specific to this candidate
1963 Int_t nTrks = trkArray->GetEntriesFast();
1964 AliVertexerTracks *vertexer = new AliVertexerTracks(event->GetMagneticField());
1966 if(fRecoPrimVtxSkippingTrks) {
1967 // recalculating the vertex
1969 if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraint")) {
1970 Float_t diamondcovxy[3];
1971 event->GetDiamondCovXY(diamondcovxy);
1972 Double_t pos[3]={event->GetDiamondX(),event->GetDiamondY(),0.};
1973 Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.*10.};
1974 AliESDVertex *diamond = new AliESDVertex(pos,cov,1.,1);
1975 vertexer->SetVtxStart(diamond);
1976 delete diamond; diamond=NULL;
1977 if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraintOnlyFitter"))
1978 vertexer->SetOnlyFitter();
1980 Int_t skipped[1000];
1981 Int_t nTrksToSkip=0,id;
1982 AliExternalTrackParam *t = 0;
1983 for(Int_t i=0; i<nTrks; i++) {
1984 t = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
1985 id = (Int_t)t->GetID();
1987 skipped[nTrksToSkip++] = id;
1990 // For AOD, skip also tracks without covariance matrix
1992 Double_t covtest[21];
1993 for(Int_t j=0; j<event->GetNumberOfTracks(); j++) {
1994 AliVTrack *vtrack = (AliVTrack*)event->GetTrack(j);
1995 if(!vtrack->GetCovarianceXYZPxPyPz(covtest)) {
1996 id = (Int_t)vtrack->GetID();
1998 skipped[nTrksToSkip++] = id;
2002 for(Int_t ijk=nTrksToSkip; ijk<1000; ijk++) skipped[ijk]=-1;
2004 vertexer->SetSkipTracks(nTrksToSkip,skipped);
2005 vertexESD = (AliESDVertex*)vertexer->FindPrimaryVertex(event);
2007 } else if(fRmTrksFromPrimVtx && nTrks>0) {
2008 // removing the prongs tracks
2010 TObjArray rmArray(nTrks);
2011 UShort_t *rmId = new UShort_t[nTrks];
2012 AliESDtrack *esdTrack = 0;
2014 for(Int_t i=0; i<nTrks; i++) {
2015 t = (AliESDtrack*)trkArray->UncheckedAt(i);
2016 esdTrack = new AliESDtrack(*t);
2017 rmArray.AddLast(esdTrack);
2018 if(esdTrack->GetID()>=0) {
2019 rmId[i]=(UShort_t)esdTrack->GetID();
2024 Float_t diamondxy[2]={event->GetDiamondX(),event->GetDiamondY()};
2025 vertexESD = vertexer->RemoveTracksFromVertex(fV1,&rmArray,rmId,diamondxy);
2026 delete [] rmId; rmId=NULL;
2031 if(!vertexESD) return vertexAOD;
2032 if(vertexESD->GetNContributors()<=0) {
2033 //AliDebug(2,"vertexing failed");
2034 delete vertexESD; vertexESD=NULL;
2038 delete vertexer; vertexer=NULL;
2042 // convert to AliAODVertex
2043 Double_t pos[3],cov[6],chi2perNDF;
2044 vertexESD->GetXYZ(pos); // position
2045 vertexESD->GetCovMatrix(cov); //covariance matrix
2046 chi2perNDF = vertexESD->GetChi2toNDF();
2047 delete vertexESD; vertexESD=NULL;
2049 vertexAOD = new AliAODVertex(pos,cov,chi2perNDF);
2053 //-----------------------------------------------------------------------------
2054 void AliAnalysisVertexingHF::PrintStatus() const {
2055 // Print parameters being used
2057 //printf("Preselections:\n");
2058 // fTrackFilter->Dump();
2060 printf("Secondary vertex with Kalman filter package (AliKFParticle)\n");
2062 printf("Secondary vertex with AliVertexerTracks\n");
2064 if(fRecoPrimVtxSkippingTrks) printf("RecoPrimVtxSkippingTrks\n");
2065 if(fRmTrksFromPrimVtx) printf("RmTrksFromPrimVtx\n");
2067 printf("Reconstruct D0->Kpi candidates with cuts:\n");
2068 if(fCutsD0toKpi) fCutsD0toKpi->PrintAll();
2071 printf("Reconstruct D*->D0pi candidates with cuts:\n");
2072 if(fFindVertexForDstar) {
2073 printf(" Reconstruct a secondary vertex for the D*\n");
2075 printf(" Assume the D* comes from the primary vertex\n");
2077 if(fCutsDStartoKpipi) fCutsDStartoKpipi->PrintAll();
2080 printf("Reconstruct J/psi from B candidates with cuts:\n");
2081 if(fCutsJpsitoee) fCutsJpsitoee->PrintAll();
2084 printf("Reconstruct 3 prong candidates.\n");
2085 printf(" D+->Kpipi cuts:\n");
2086 if(fCutsDplustoKpipi) fCutsDplustoKpipi->PrintAll();
2087 printf(" Ds->KKpi cuts:\n");
2088 if(fCutsDstoKKpi) fCutsDstoKKpi->PrintAll();
2089 printf(" Lc->pKpi cuts:\n");
2090 if(fCutsLctopKpi) fCutsLctopKpi->PrintAll();
2093 printf("Reconstruct 4 prong candidates.\n");
2094 printf(" D0->Kpipipi cuts:\n");
2095 if(fCutsD0toKpipipi) fCutsD0toKpipipi->PrintAll();
2098 printf("Reconstruct cascades candidates formed with v0s.\n");
2099 printf(" Lc -> k0s P & Lc -> L Pi cuts:\n");
2100 if(fCutsLctoV0) fCutsLctoV0->PrintAll();
2105 //-----------------------------------------------------------------------------
2106 AliAODVertex* AliAnalysisVertexingHF::ReconstructSecondaryVertex(TObjArray *trkArray,
2107 Double_t &dispersion,Bool_t useTRefArray) const
2109 // Secondary vertex reconstruction with AliVertexerTracks or AliKFParticle
2110 //AliCodeTimerAuto("",0);
2112 AliESDVertex *vertexESD = 0;
2113 AliAODVertex *vertexAOD = 0;
2115 if(!fSecVtxWithKF) { // AliVertexerTracks
2117 fVertexerTracks->SetVtxStart(fV1);
2118 vertexESD = (AliESDVertex*)fVertexerTracks->VertexForSelectedESDTracks(trkArray);
2120 if(!vertexESD) return vertexAOD;
2122 if(vertexESD->GetNContributors()!=trkArray->GetEntriesFast()) {
2123 //AliDebug(2,"vertexing failed");
2124 delete vertexESD; vertexESD=NULL;
2128 Double_t vertRadius2=vertexESD->GetXv()*vertexESD->GetXv()+vertexESD->GetYv()*vertexESD->GetYv();
2130 // vertex outside beam pipe, reject candidate to avoid propagation through material
2131 delete vertexESD; vertexESD=NULL;
2135 } else { // Kalman Filter vertexer (AliKFParticle)
2137 AliKFParticle::SetField(fBzkG);
2139 AliKFVertex vertexKF;
2141 Int_t nTrks = trkArray->GetEntriesFast();
2142 for(Int_t i=0; i<nTrks; i++) {
2143 AliESDtrack *esdTrack = (AliESDtrack*)trkArray->At(i);
2144 AliKFParticle daughterKF(*esdTrack,211);
2145 vertexKF.AddDaughter(daughterKF);
2147 vertexESD = new AliESDVertex(vertexKF.Parameters(),
2148 vertexKF.CovarianceMatrix(),
2150 vertexKF.GetNContributors());
2154 // convert to AliAODVertex
2155 Double_t pos[3],cov[6],chi2perNDF;
2156 vertexESD->GetXYZ(pos); // position
2157 vertexESD->GetCovMatrix(cov); //covariance matrix
2158 chi2perNDF = vertexESD->GetChi2toNDF();
2159 dispersion = vertexESD->GetDispersion();
2160 delete vertexESD; vertexESD=NULL;
2162 Int_t nprongs= (useTRefArray ? 0 : trkArray->GetEntriesFast());
2163 vertexAOD = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,nprongs);
2167 //-----------------------------------------------------------------------------
2168 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPt3prong(TObjArray *trkArray){
2169 // Invariant mass cut on tracks
2170 //AliCodeTimerAuto("",0);
2172 Int_t retval=kFALSE;
2173 Double_t momentum[3];
2174 Double_t px[3],py[3],pz[3];
2175 for(Int_t iTrack=0; iTrack<3; iTrack++){
2176 AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
2177 track->GetPxPyPz(momentum);
2178 px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
2180 retval = SelectInvMassAndPt3prong(px,py,pz);
2185 //-----------------------------------------------------------------------------
2186 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPt4prong(TObjArray *trkArray){
2187 // Invariant mass cut on tracks
2188 //AliCodeTimerAuto("",0);
2190 Int_t retval=kFALSE;
2191 Double_t momentum[3];
2192 Double_t px[4],py[4],pz[4];
2194 for(Int_t iTrack=0; iTrack<4; iTrack++){
2195 AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
2196 track->GetPxPyPz(momentum);
2197 px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
2200 retval = SelectInvMassAndPt4prong(px,py,pz);
2204 //-----------------------------------------------------------------------------
2205 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtDstarD0pi(TObjArray *trkArray){
2206 // Invariant mass cut on tracks
2207 //AliCodeTimerAuto("",0);
2209 Int_t retval=kFALSE;
2210 Double_t momentum[3];
2211 Double_t px[2],py[2],pz[2];
2213 for(Int_t iTrack=0; iTrack<2; iTrack++){
2214 AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
2215 track->GetPxPyPz(momentum);
2216 px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
2218 retval = SelectInvMassAndPtDstarD0pi(px,py,pz);
2222 //-----------------------------------------------------------------------------
2223 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtD0Kpi(Double_t *px,
2226 // Check invariant mass cut and pt candidate cut
2227 //AliCodeTimerAuto("",0);
2231 Double_t minv2,mrange;
2232 Double_t lolim,hilim;
2234 Bool_t retval=kFALSE;
2236 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
2237 fOKInvMassD0=kFALSE;
2239 minPt=fCutsD0toKpi->GetMinPtCandidate();
2241 if(fMassCalc2->Pt2() < minPt*minPt) return retval;
2243 mrange=fCutsD0toKpi->GetMassCut();
2244 lolim=fMassDzero-mrange;
2245 hilim=fMassDzero+mrange;
2246 pdg2[0]=211; pdg2[1]=321;
2247 minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
2248 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2252 pdg2[0]=321; pdg2[1]=211;
2253 minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
2254 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2261 //-----------------------------------------------------------------------------
2262 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtJpsiee(Double_t *px,
2265 // Check invariant mass cut and pt candidate cut
2266 //AliCodeTimerAuto("",0);
2270 Double_t minv2,mrange;
2271 Double_t lolim,hilim;
2273 Bool_t retval=kFALSE;
2275 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
2276 fOKInvMassJpsi=kFALSE;
2278 minPt=fCutsJpsitoee->GetMinPtCandidate();
2280 if(fMassCalc2->Pt2() < minPt*minPt) return retval;
2282 mrange=fCutsJpsitoee->GetMassCut();
2283 lolim=fMassJpsi-mrange;
2284 hilim=fMassJpsi+mrange;
2286 pdg2[0]=11; pdg2[1]=11;
2287 minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
2288 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2290 fOKInvMassJpsi=kTRUE;
2295 //-----------------------------------------------------------------------------
2296 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPt3prong(Double_t *px,
2299 // Check invariant mass cut and pt candidate cut
2300 //AliCodeTimerAuto("",0);
2304 Double_t minv2,mrange;
2305 Double_t lolim,hilim;
2307 Bool_t retval=kFALSE;
2310 fMassCalc3->SetPxPyPzProngs(nprongs,px,py,pz);
2311 fOKInvMassDplus=kFALSE;
2312 fOKInvMassDs=kFALSE;
2313 fOKInvMassLc=kFALSE;
2315 minPt=TMath::Min(fCutsDplustoKpipi->GetMinPtCandidate(),fCutsDstoKKpi->GetMinPtCandidate());
2316 minPt=TMath::Min(minPt,fCutsLctopKpi->GetMinPtCandidate());
2318 if(fMassCalc3->Pt2() < minPt*minPt) return retval;
2320 mrange=fCutsDplustoKpipi->GetMassCut();
2321 lolim=fMassDplus-mrange;
2322 hilim=fMassDplus+mrange;
2323 pdg3[0]=211; pdg3[1]=321; pdg3[2]=211;
2324 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2325 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2327 fOKInvMassDplus=kTRUE;
2330 mrange=fCutsDstoKKpi->GetMassCut();
2331 lolim=fMassDs-mrange;
2332 hilim=fMassDs+mrange;
2333 pdg3[0]=321; pdg3[1]=321; pdg3[2]=211;
2334 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2335 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2339 pdg3[0]=211; pdg3[1]=321; pdg3[2]=321;
2340 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2341 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2346 mrange=fCutsLctopKpi->GetMassCut();
2347 lolim=fMassLambdaC-mrange;
2348 hilim=fMassLambdaC+mrange;
2349 pdg3[0]=2212; pdg3[1]=321; pdg3[2]=211;
2350 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2351 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2355 pdg3[0]=211; pdg3[1]=321; pdg3[2]=2212;
2356 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2357 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2365 //-----------------------------------------------------------------------------
2366 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtDstarD0pi(Double_t *px,
2369 // Check invariant mass cut and pt candidate cut
2370 //AliCodeTimerAuto("",0);
2374 Double_t minv2,mrange;
2375 Double_t lolim,hilim;
2377 Bool_t retval=kFALSE;
2379 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
2380 fOKInvMassDstar=kFALSE;
2382 minPt=fCutsDStartoKpipi->GetMinPtCandidate();
2384 if(fMassCalc2->Pt2() < minPt*minPt) return retval;
2386 pdg2[0]=211; pdg2[1]=421; // in twoTrackArrayCasc we put the pion first
2387 mrange=fCutsDStartoKpipi->GetMassCut();
2388 lolim=fMassDstar-mrange;
2389 hilim=fMassDstar+mrange;
2390 minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
2391 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2393 fOKInvMassDstar=kTRUE;
2399 //-----------------------------------------------------------------------------
2400 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPt4prong(Double_t *px,
2403 // Check invariant mass cut and pt candidate cut
2404 //AliCodeTimerAuto("",0);
2408 Double_t minv2,mrange;
2409 Double_t lolim,hilim;
2411 Bool_t retval=kFALSE;
2413 // D0->Kpipipi without PID
2414 fMassCalc4->SetPxPyPzProngs(nprongs,px,py,pz);
2415 fOKInvMassD0to4p=kFALSE;
2417 minPt=fCutsD0toKpipipi->GetMinPtCandidate();
2419 if(fMassCalc4->Pt2() < minPt*minPt) return retval;
2421 mrange=fCutsD0toKpipipi->GetMassCut();
2422 lolim=fMassDzero-mrange;
2423 hilim=fMassDzero+mrange;
2425 pdg4[0]=321; pdg4[1]=211; pdg4[2]=211; pdg4[3]=211;
2426 minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
2427 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2429 fOKInvMassD0to4p=kTRUE;
2432 pdg4[0]=211; pdg4[1]=321; pdg4[2]=211; pdg4[3]=211;
2433 minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
2434 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2436 fOKInvMassD0to4p=kTRUE;
2439 pdg4[0]=211; pdg4[1]=211; pdg4[2]=321; pdg4[3]=211;
2440 minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
2441 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2443 fOKInvMassD0to4p=kTRUE;
2446 pdg4[0]=211; pdg4[1]=211; pdg4[2]=211; pdg4[3]=321;
2447 minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
2448 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2450 fOKInvMassD0to4p=kTRUE;
2455 //-----------------------------------------------------------------------------
2456 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtCascade(Double_t *px,
2459 // Check invariant mass cut and pt candidate cut
2460 //AliCodeTimerAuto("",0);
2464 Double_t minv2,mrange;
2465 Double_t lolim,hilim;
2467 Bool_t retval=kFALSE;
2469 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
2470 minPt=fCutsLctoV0->GetMinPtCandidate();
2471 fOKInvMassLctoV0=kFALSE;
2472 mrange=fCutsLctoV0->GetMassCut();
2473 lolim=fMassLambdaC-mrange;
2474 hilim=fMassLambdaC+mrange;
2475 pdg2[0]=2212;pdg2[1]=310;
2476 minv2=fMassCalc2->InvMass2(2,pdg2);
2477 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2479 fOKInvMassLctoV0=kTRUE;
2481 pdg2[0]=211;pdg2[1]=3122;
2482 minv2=fMassCalc2->InvMass2(2,pdg2);
2483 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2485 fOKInvMassLctoV0=kTRUE;
2490 //-----------------------------------------------------------------------------
2491 void AliAnalysisVertexingHF::SelectTracksAndCopyVertex(const AliVEvent *event,
2493 TObjArray &seleTrksArray,
2494 TObjArray &tracksAtVertex,
2496 UChar_t *seleFlags,Int_t *evtNumber)
2498 // Apply single-track preselection.
2499 // Fill a TObjArray with selected tracks (for displaced vertices or
2500 // soft pion from D*). Selection flag stored in seleFlags.
2501 // Create the AliESDVertex object (convert from AliAODVertex if necessary)
2502 // In case of AOD input, also fill fAODMap for track index<->ID
2503 //AliCodeTimerAuto("",0);
2505 const AliVVertex *vprimary = event->GetPrimaryVertex();
2507 if(fV1) { delete fV1; fV1=NULL; }
2508 if(fAODMap) { delete [] fAODMap; fAODMap=NULL; }
2511 UShort_t *indices = 0;
2512 Double_t pos[3],cov[6];
2513 const Int_t entries = event->GetNumberOfTracks();
2514 AliCentrality* cent;
2516 if(!fInputAOD) { // ESD
2517 fV1 = new AliESDVertex(*((AliESDVertex*)vprimary));
2518 cent=((AliESDEvent*)event)->GetCentrality();
2520 vprimary->GetXYZ(pos);
2521 vprimary->GetCovarianceMatrix(cov);
2522 fV1 = new AliESDVertex(pos,cov,100.,100,vprimary->GetName());
2523 if(entries<=0) return;
2524 indices = new UShort_t[entries];
2525 memset(indices,0,sizeof(UShort_t)*entries);
2526 fAODMapSize = 100000;
2527 fAODMap = new Int_t[fAODMapSize];
2528 memset(fAODMap,0,sizeof(Int_t)*fAODMapSize);
2529 cent=((AliAODEvent*)event)->GetCentrality();
2531 Float_t centperc=cent->GetCentralityPercentile("V0M");
2533 Bool_t okDisplaced=kFALSE,okSoftPi=kFALSE,okFor3Prong=kFALSE;
2536 // transfer ITS tracks from event to arrays
2537 for(Int_t i=0; i<entries; i++) {
2539 track = (AliVTrack*)event->GetTrack(i);
2541 // skip pure ITS SA tracks
2542 if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
2544 // skip tracks without ITS
2545 if(!(track->GetStatus()&AliESDtrack::kITSin)) continue;
2547 // skip tracks with negative ID
2548 // (these are duplicated TPC-only AOD tracks, for jet analysis...)
2549 if(track->GetID()<0) continue;
2551 // TEMPORARY: check that the cov matrix is there
2552 Double_t covtest[21];
2553 if(!track->GetCovarianceXYZPxPyPz(covtest)) continue;
2557 AliAODTrack *aodt = (AliAODTrack*)track;
2558 if(aodt->GetUsedForPrimVtxFit()) {
2559 indices[nindices]=aodt->GetID(); nindices++;
2561 Int_t ind = (Int_t)aodt->GetID();
2562 if (ind>-1 && ind < fAODMapSize) fAODMap[ind] = i;
2565 AliESDtrack *esdt = 0;
2568 esdt = (AliESDtrack*)track;
2570 esdt = new AliESDtrack(track);
2573 // single track selection
2574 okDisplaced=kFALSE; okSoftPi=kFALSE; okFor3Prong=kFALSE;
2575 if(fMixEvent && i<trkEntries){
2576 evtNumber[i]=((AliMixedEvent*)event)->EventIndex(i);
2577 const AliVVertex* eventVtx=((AliMixedEvent*)event)->GetEventVertex(i);
2578 Double_t vtxPos[3],primPos[3],primCov[6],trasl[3];
2579 eventVtx->GetXYZ(vtxPos);
2580 vprimary->GetXYZ(primPos);
2581 eventVtx->GetCovarianceMatrix(primCov);
2582 for(Int_t ind=0;ind<3;ind++){
2583 trasl[ind]=vtxPos[ind]-primPos[ind];
2586 Bool_t isTransl=esdt->Translate(trasl,primCov);
2594 if(SingleTrkCuts(esdt,centperc,okDisplaced,okSoftPi,okFor3Prong) && nSeleTrks<trkEntries) {
2595 esdt->PropagateToDCA(fV1,fBzkG,kVeryBig);
2596 seleTrksArray.AddLast(esdt);
2597 tracksAtVertex.AddLast(new AliExternalTrackParam(*esdt));
2598 seleFlags[nSeleTrks]=0;
2599 if(okDisplaced) SETBIT(seleFlags[nSeleTrks],kBitDispl);
2600 if(okFor3Prong) SETBIT(seleFlags[nSeleTrks],kBit3Prong);
2601 if(okSoftPi) SETBIT(seleFlags[nSeleTrks],kBitSoftPi);
2604 if(fInputAOD) delete esdt;
2609 } // end loop on tracks
2611 // primary vertex from AOD
2613 delete fV1; fV1=NULL;
2614 vprimary->GetXYZ(pos);
2615 vprimary->GetCovarianceMatrix(cov);
2616 Double_t chi2toNDF = vprimary->GetChi2perNDF();
2617 Int_t ncontr=nindices;
2618 if(!strcmp(vprimary->GetTitle(),"VertexerTracksWithContraint")) ncontr += 1;
2619 Double_t chi2=chi2toNDF*(2.*(Double_t)ncontr-3.);
2620 fV1 = new AliESDVertex(pos,cov,chi2,ncontr,vprimary->GetName());
2621 fV1->SetTitle(vprimary->GetTitle());
2622 fV1->SetIndices(nindices,indices);
2624 if(indices) { delete [] indices; indices=NULL; }
2629 //-----------------------------------------------------------------------------
2630 void AliAnalysisVertexingHF::SetSelectionBitForPID(AliRDHFCuts *cuts,AliAODRecoDecayHF *rd,Int_t bit) {
2632 // Set the selection bit for PID
2634 //AliCodeTimerAuto("",0);
2635 if(cuts->GetPidHF()) {
2636 Bool_t usepid=cuts->GetIsUsePID();
2637 cuts->SetUsePID(kTRUE);
2638 if(cuts->IsSelectedPID(rd))
2639 rd->SetSelectionBit(bit);
2640 cuts->SetUsePID(usepid);
2644 //-----------------------------------------------------------------------------
2645 Bool_t AliAnalysisVertexingHF::SingleTrkCuts(AliESDtrack *trk,
2646 Float_t centralityperc,
2647 Bool_t &okDisplaced,
2649 Bool_t &okFor3Prong) const
2651 // Check if track passes some kinematical cuts
2653 // this is needed to store the impact parameters
2654 //AliCodeTimerAuto("",0);
2656 trk->RelateToVertex(fV1,fBzkG,kVeryBig);
2660 // Track selection, displaced tracks -- 2 prong
2662 if(centralityperc>=0 && fMaxCentPercentileForTightCuts>=0
2663 && fTrackFilter2prongCentral && centralityperc<fMaxCentPercentileForTightCuts){
2664 // central PbPb events, tighter cuts
2665 selectInfo = fTrackFilter2prongCentral->IsSelected(trk);
2669 selectInfo = fTrackFilter->IsSelected(trk);
2672 if(selectInfo) okDisplaced=kTRUE;
2674 // Track selection, displaced tracks -- 3 prong
2676 if(centralityperc>=0 && fMaxCentPercentileForTightCuts>=0
2677 && fTrackFilter3prongCentral && centralityperc<fMaxCentPercentileForTightCuts){
2678 // central PbPb events, tighter cuts
2679 selectInfo = fTrackFilter3prongCentral->IsSelected(trk);
2683 selectInfo = fTrackFilter->IsSelected(trk);
2686 if(selectInfo) okFor3Prong=kTRUE;
2688 // Track selection, soft pions
2690 if(fDstar && fTrackFilterSoftPi) {
2691 selectInfo = fTrackFilterSoftPi->IsSelected(trk);
2693 if(selectInfo) okSoftPi=kTRUE;
2695 if(okDisplaced || okSoftPi || okFor3Prong) return kTRUE;
2701 //-----------------------------------------------------------------------------
2702 AliAODv0* AliAnalysisVertexingHF::TransformESDv0toAODv0(AliESDv0 *esdV0, TObjArray *twoTrackArrayV0){
2704 // Transform ESDv0 to AODv0
2706 // this function takes the ESDv0 vertex, computes the DCA variables from the ESDv0
2707 // and creates an AODv0 out of them
2709 //AliCodeTimerAuto("",0);
2710 Double_t vertex[3]; esdV0->GetXYZ(vertex[0],vertex[1],vertex[2]);
2711 AliAODVertex *vertexV0 = new AliAODVertex(vertex,esdV0->GetChi2V0(),AliAODVertex::kV0,2);
2713 // create the v0 neutral track to compute the DCA to the primary vertex
2714 Double_t xyz[3], pxpypz[3];
2716 esdV0->PxPyPz(pxpypz);
2717 Double_t cv[21]; for(int i=0; i<21; i++) cv[i]=0;
2718 AliNeutralTrackParam *trackesdV0 = new AliNeutralTrackParam(xyz,pxpypz,cv,0);
2723 Double_t d0z0[2],covd0z0[3];
2724 AliAODVertex *primVertexAOD = PrimaryVertex();
2725 trackesdV0->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2726 Double_t dcaV0ToPrimVertex = TMath::Sqrt(covd0z0[0]);
2727 // get the v0 daughters to compute their DCA to the v0 vertex and get their momentum
2728 Double_t dcaV0DaughterToPrimVertex[2];
2729 AliExternalTrackParam *posV0track = (AliExternalTrackParam*)twoTrackArrayV0->UncheckedAt(0);
2730 AliExternalTrackParam *negV0track = (AliExternalTrackParam*)twoTrackArrayV0->UncheckedAt(1);
2731 if( !posV0track || !negV0track) {
2732 if(trackesdV0) {delete trackesdV0; trackesdV0=NULL;}
2734 delete primVertexAOD;
2737 posV0track->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2738 // if ( covd0z0[0]<=0.) dcaV0DaughterToPrimVertex[0] = 0;
2740 dcaV0DaughterToPrimVertex[0] = TMath::Sqrt(covd0z0[0]);
2741 negV0track->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2742 // if ( covd0z0[0]<=0.)dcaV0DaughterToPrimVertex[1] = 0;
2744 dcaV0DaughterToPrimVertex[1] = TMath::Sqrt(covd0z0[0]);
2745 Double_t dcaV0Daughters = esdV0->GetDcaV0Daughters();
2746 Double_t pmom[3],nmom[3];
2747 esdV0->GetNPxPyPz(nmom[0],nmom[1],nmom[2]);
2748 esdV0->GetPPxPyPz(pmom[0],pmom[1],pmom[2]);
2750 AliAODv0 *aodV0 = new AliAODv0(vertexV0,dcaV0Daughters,dcaV0ToPrimVertex,pmom,nmom,dcaV0DaughterToPrimVertex);
2751 aodV0->SetOnFlyStatus(esdV0->GetOnFlyStatus());
2754 delete primVertexAOD;
2758 //-----------------------------------------------------------------------------
2759 void AliAnalysisVertexingHF::SetParametersAtVertex(AliESDtrack* esdt, const AliExternalTrackParam* extpar) const{
2760 // Set the stored track parameters at primary vertex into AliESDtrack
2761 //AliCodeTimerAuto("",0);
2763 const Double_t *par=extpar->GetParameter();
2764 const Double_t *cov=extpar->GetCovariance();
2765 Double_t alpha=extpar->GetAlpha();
2766 Double_t x=extpar->GetX();
2767 esdt->Set(x,alpha,par,cov);
2770 //-----------------------------------------------------------------------------
2771 void AliAnalysisVertexingHF::SetMasses(){
2772 // Set the hadron mass values from TDatabasePDG
2774 fMassDzero=TDatabasePDG::Instance()->GetParticle(421)->Mass();
2775 fMassDplus=TDatabasePDG::Instance()->GetParticle(411)->Mass();
2776 fMassDs=TDatabasePDG::Instance()->GetParticle(431)->Mass();
2777 fMassLambdaC=TDatabasePDG::Instance()->GetParticle(4122)->Mass();
2778 fMassDstar=TDatabasePDG::Instance()->GetParticle(413)->Mass();
2779 fMassJpsi=TDatabasePDG::Instance()->GetParticle(443)->Mass();
2781 //-----------------------------------------------------------------------------
2782 Bool_t AliAnalysisVertexingHF::CheckCutsConsistency(){
2784 // Check the Vertexer and the analysts task consitstecny
2788 //___ Check if the V0 type from AliRDHFCutsLctoV0 is the same as the one set in the ConfigVertexingHF.C for AliAnalysisVertexingHF
2791 if ( fCutsLctoV0 && fV0TypeForCascadeVertex != fCutsLctoV0->GetV0Type())
2793 printf("ERROR: V0 type doesn not match in AliAnalysisVertexingHF (%d) required in AliRDHFCutsLctoV0 (%d)\n",fV0TypeForCascadeVertex,fCutsLctoV0->GetV0Type());
2798 //-----------------------------------------------------------------------------