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),
96 fUseKaonPIDforDs(kFALSE),
99 fUseTPCPIDOnlyIfNoTOF(kFALSE),
100 fMaxMomForTPCPid(1.),
101 fnSigmaTPCPionLow(5.),
102 fnSigmaTPCPionHi(5.),
103 fnSigmaTOFPionLow(5.),
104 fnSigmaTOFPionHi(5.),
105 fnSigmaTPCKaonLow(5.),
106 fnSigmaTPCKaonHi(5.),
107 fnSigmaTOFKaonLow(5.),
108 fnSigmaTOFKaonHi(5.),
109 fnSigmaTPCProtonLow(5.),
110 fnSigmaTPCProtonHi(5.),
111 fnSigmaTOFProtonLow(5.),
112 fnSigmaTOFProtonHi(5.),
113 fMaxCentPercentileForTightCuts(-9999),
115 fTrackFilter2prongCentral(0x0),
116 fTrackFilter3prongCentral(0x0),
117 fTrackFilterSoftPi(0x0),
120 fCutsDplustoKpipi(0x0),
124 fCutsD0toKpipipi(0x0),
125 fCutsDStartoKpipi(0x0),
127 fFindVertexForDstar(kTRUE),
128 fFindVertexForCascades(kTRUE),
129 fV0TypeForCascadeVertex(0),
130 fMassCutBeforeVertexing(kFALSE),
134 fOKInvMassD0(kFALSE),
135 fOKInvMassJpsi(kFALSE),
136 fOKInvMassDplus(kFALSE),
137 fOKInvMassDs(kFALSE),
138 fOKInvMassLc(kFALSE),
139 fOKInvMassDstar(kFALSE),
140 fOKInvMassD0to4p(kFALSE),
141 fOKInvMassLctoV0(kFALSE),
151 // Default constructor
153 Double_t d02[2]={0.,0.};
154 Double_t d03[3]={0.,0.,0.};
155 Double_t d04[4]={0.,0.,0.,0.};
156 fMassCalc2 = new AliAODRecoDecay(0x0,2,0,d02);
157 fMassCalc3 = new AliAODRecoDecay(0x0,3,1,d03);
158 fMassCalc4 = new AliAODRecoDecay(0x0,4,0,d04);
161 //--------------------------------------------------------------------------
162 AliAnalysisVertexingHF::AliAnalysisVertexingHF(const AliAnalysisVertexingHF &source) :
164 fInputAOD(source.fInputAOD),
165 fAODMapSize(source.fAODMapSize),
166 fAODMap(source.fAODMap),
167 fVertexerTracks(source.fVertexerTracks),
169 fSecVtxWithKF(source.fSecVtxWithKF),
170 fRecoPrimVtxSkippingTrks(source.fRecoPrimVtxSkippingTrks),
171 fRmTrksFromPrimVtx(source.fRmTrksFromPrimVtx),
173 fD0toKpi(source.fD0toKpi),
174 fJPSItoEle(source.fJPSItoEle),
175 f3Prong(source.f3Prong),
176 f4Prong(source.f4Prong),
177 fDstar(source.fDstar),
178 fCascades(source.fCascades),
179 fLikeSign(source.fLikeSign),
180 fLikeSign3prong(source.fLikeSign3prong),
181 fMixEvent(source.fMixEvent),
182 fPidResponse(source.fPidResponse),
183 fUseKaonPIDfor3Prong(source.fUseKaonPIDfor3Prong),
184 fUsePIDforLc(source.fUsePIDforLc),
185 fUsePIDforLc2V0(source.fUsePIDforLc2V0),
186 fUseKaonPIDforDs(source.fUseKaonPIDforDs),
187 fUseTPCPID(source.fUseTPCPID),
188 fUseTOFPID(source.fUseTOFPID),
189 fUseTPCPIDOnlyIfNoTOF(source.fUseTPCPIDOnlyIfNoTOF),
190 fMaxMomForTPCPid(source.fMaxMomForTPCPid),
191 fnSigmaTPCPionLow(source.fnSigmaTPCPionLow),
192 fnSigmaTPCPionHi(source.fnSigmaTPCPionHi),
193 fnSigmaTOFPionLow(source.fnSigmaTOFPionLow),
194 fnSigmaTOFPionHi(source.fnSigmaTOFPionHi),
195 fnSigmaTPCKaonLow(source.fnSigmaTPCKaonLow),
196 fnSigmaTPCKaonHi(source.fnSigmaTPCKaonHi),
197 fnSigmaTOFKaonLow(source.fnSigmaTOFKaonLow),
198 fnSigmaTOFKaonHi(source.fnSigmaTOFKaonHi),
199 fnSigmaTPCProtonLow(source.fnSigmaTPCProtonLow),
200 fnSigmaTPCProtonHi(source.fnSigmaTPCProtonHi),
201 fnSigmaTOFProtonLow(source.fnSigmaTOFProtonLow),
202 fnSigmaTOFProtonHi(source.fnSigmaTOFProtonHi),
203 fMaxCentPercentileForTightCuts(source.fMaxCentPercentileForTightCuts),
204 fTrackFilter(source.fTrackFilter),
205 fTrackFilter2prongCentral(source.fTrackFilter2prongCentral),
206 fTrackFilter3prongCentral(source.fTrackFilter3prongCentral),
207 fTrackFilterSoftPi(source.fTrackFilterSoftPi),
208 fCutsD0toKpi(source.fCutsD0toKpi),
209 fCutsJpsitoee(source.fCutsJpsitoee),
210 fCutsDplustoKpipi(source.fCutsDplustoKpipi),
211 fCutsDstoKKpi(source.fCutsDstoKKpi),
212 fCutsLctopKpi(source.fCutsLctopKpi),
213 fCutsLctoV0(source.fCutsLctoV0),
214 fCutsD0toKpipipi(source.fCutsD0toKpipipi),
215 fCutsDStartoKpipi(source.fCutsDStartoKpipi),
216 fListOfCuts(source.fListOfCuts),
217 fFindVertexForDstar(source.fFindVertexForDstar),
218 fFindVertexForCascades(source.fFindVertexForCascades),
219 fV0TypeForCascadeVertex(source.fV0TypeForCascadeVertex),
220 fMassCutBeforeVertexing(source.fMassCutBeforeVertexing),
221 fMassCalc2(source.fMassCalc2),
222 fMassCalc3(source.fMassCalc3),
223 fMassCalc4(source.fMassCalc4),
224 fOKInvMassD0(source.fOKInvMassD0),
225 fOKInvMassJpsi(source.fOKInvMassJpsi),
226 fOKInvMassDplus(source.fOKInvMassDplus),
227 fOKInvMassDs(source.fOKInvMassDs),
228 fOKInvMassLc(source.fOKInvMassLc),
229 fOKInvMassDstar(source.fOKInvMassDstar),
230 fOKInvMassD0to4p(source.fOKInvMassD0to4p),
231 fOKInvMassLctoV0(source.fOKInvMassLctoV0),
234 fMassDzero(source.fMassDzero),
235 fMassDplus(source.fMassDplus),
236 fMassDs(source.fMassDs),
237 fMassLambdaC(source.fMassLambdaC),
238 fMassDstar(source.fMassDstar),
239 fMassJpsi(source.fMassJpsi)
245 //--------------------------------------------------------------------------
246 AliAnalysisVertexingHF &AliAnalysisVertexingHF::operator=(const AliAnalysisVertexingHF &source)
249 // assignment operator
251 if(&source == this) return *this;
252 fInputAOD = source.fInputAOD;
253 fAODMapSize = source.fAODMapSize;
254 fVertexerTracks = source.fVertexerTracks;
255 fBzkG = source.fBzkG;
256 fSecVtxWithKF = source.fSecVtxWithKF;
257 fRecoPrimVtxSkippingTrks = source.fRecoPrimVtxSkippingTrks;
258 fRmTrksFromPrimVtx = source.fRmTrksFromPrimVtx;
260 fD0toKpi = source.fD0toKpi;
261 fJPSItoEle = source.fJPSItoEle;
262 f3Prong = source.f3Prong;
263 f4Prong = source.f4Prong;
264 fDstar = source.fDstar;
265 fCascades = source.fCascades;
266 fLikeSign = source.fLikeSign;
267 fLikeSign3prong = source.fLikeSign3prong;
268 fMixEvent = source.fMixEvent;
269 fPidResponse = source.fPidResponse;
270 fUseKaonPIDfor3Prong = source.fUseKaonPIDfor3Prong;
271 fUsePIDforLc = source.fUsePIDforLc;
272 fUsePIDforLc2V0 = source.fUsePIDforLc2V0;
273 fUseKaonPIDforDs = source.fUseKaonPIDforDs;
274 fUseTPCPID = source.fUseTPCPID;
275 fUseTOFPID = source.fUseTOFPID;
276 fUseTPCPIDOnlyIfNoTOF = source.fUseTPCPIDOnlyIfNoTOF;
277 fMaxMomForTPCPid = source.fMaxMomForTPCPid;
278 fnSigmaTPCPionLow = source.fnSigmaTPCPionLow;
279 fnSigmaTPCPionHi = source.fnSigmaTPCPionHi;
280 fnSigmaTOFPionLow = source.fnSigmaTOFPionLow;
281 fnSigmaTOFPionHi = source.fnSigmaTOFPionHi;
282 fnSigmaTPCKaonLow = source.fnSigmaTPCKaonLow;
283 fnSigmaTPCKaonHi = source.fnSigmaTPCKaonHi;
284 fnSigmaTOFKaonLow = source.fnSigmaTOFKaonLow;
285 fnSigmaTOFKaonHi = source.fnSigmaTOFKaonHi;
286 fnSigmaTPCProtonLow = source.fnSigmaTPCProtonLow;
287 fnSigmaTPCProtonHi = source.fnSigmaTPCProtonHi;
288 fnSigmaTOFProtonLow = source.fnSigmaTOFProtonLow;
289 fnSigmaTOFProtonHi = source.fnSigmaTOFProtonHi;
290 fnSigmaTOFKaonLow = source.fnSigmaTOFKaonLow;
291 fnSigmaTOFKaonHi = source.fnSigmaTOFKaonHi;
292 fMaxCentPercentileForTightCuts = source.fMaxCentPercentileForTightCuts;
293 fTrackFilter = source.fTrackFilter;
294 fTrackFilter2prongCentral = source.fTrackFilter2prongCentral;
295 fTrackFilter3prongCentral = source.fTrackFilter3prongCentral;
296 fTrackFilterSoftPi = source.fTrackFilterSoftPi;
297 fCutsD0toKpi = source.fCutsD0toKpi;
298 fCutsJpsitoee = source.fCutsJpsitoee;
299 fCutsDplustoKpipi = source.fCutsDplustoKpipi;
300 fCutsDstoKKpi = source.fCutsDstoKKpi;
301 fCutsLctopKpi = source.fCutsLctopKpi;
302 fCutsLctoV0 = source.fCutsLctoV0;
303 fCutsD0toKpipipi = source.fCutsD0toKpipipi;
304 fCutsDStartoKpipi = source.fCutsDStartoKpipi;
305 fListOfCuts = source.fListOfCuts;
306 fFindVertexForDstar = source.fFindVertexForDstar;
307 fFindVertexForCascades = source.fFindVertexForCascades;
308 fV0TypeForCascadeVertex = source.fV0TypeForCascadeVertex;
309 fMassCutBeforeVertexing = source.fMassCutBeforeVertexing;
310 fMassCalc2 = source.fMassCalc2;
311 fMassCalc3 = source.fMassCalc3;
312 fMassCalc4 = source.fMassCalc4;
313 fOKInvMassD0 = source.fOKInvMassD0;
314 fOKInvMassJpsi = source.fOKInvMassJpsi;
315 fOKInvMassDplus = source.fOKInvMassDplus;
316 fOKInvMassDs = source.fOKInvMassDs;
317 fOKInvMassLc = source.fOKInvMassLc;
318 fOKInvMassDstar = source.fOKInvMassDstar;
319 fOKInvMassD0to4p = source.fOKInvMassD0to4p;
320 fOKInvMassLctoV0 = source.fOKInvMassLctoV0;
321 fMassDzero = source.fMassDzero;
322 fMassDplus = source.fMassDplus;
323 fMassDs = source.fMassDs;
324 fMassLambdaC = source.fMassLambdaC;
325 fMassDstar = source.fMassDstar;
326 fMassJpsi = source.fMassJpsi;
330 //----------------------------------------------------------------------------
331 AliAnalysisVertexingHF::~AliAnalysisVertexingHF() {
333 if(fV1) { delete fV1; fV1=0; }
334 delete fVertexerTracks;
335 if(fTrackFilter) { delete fTrackFilter; fTrackFilter=0; }
336 if(fTrackFilter2prongCentral) { delete fTrackFilter2prongCentral; fTrackFilter2prongCentral=0; }
337 if(fTrackFilter3prongCentral) { delete fTrackFilter3prongCentral; fTrackFilter3prongCentral=0; }
338 if(fTrackFilterSoftPi) { delete fTrackFilterSoftPi; fTrackFilterSoftPi=0; }
339 if(fCutsD0toKpi) { delete fCutsD0toKpi; fCutsD0toKpi=0; }
340 if(fCutsJpsitoee) { delete fCutsJpsitoee; fCutsJpsitoee=0; }
341 if(fCutsDplustoKpipi) { delete fCutsDplustoKpipi; fCutsDplustoKpipi=0; }
342 if(fCutsDstoKKpi) { delete fCutsDstoKKpi; fCutsDstoKKpi=0; }
343 if(fCutsLctopKpi) { delete fCutsLctopKpi; fCutsLctopKpi=0; }
344 if(fCutsLctoV0) { delete fCutsLctoV0; fCutsLctoV0=0; }
345 if(fCutsD0toKpipipi) { delete fCutsD0toKpipipi; fCutsD0toKpipipi=0; }
346 if(fCutsDStartoKpipi) { delete fCutsDStartoKpipi; fCutsDStartoKpipi=0; }
347 if(fAODMap) { delete [] fAODMap; fAODMap=0; }
348 if(fMassCalc2) { delete fMassCalc2; fMassCalc2=0; }
349 if(fMassCalc3) { delete fMassCalc3; fMassCalc3=0; }
350 if(fMassCalc4) { delete fMassCalc4; fMassCalc4=0; }
352 //----------------------------------------------------------------------------
353 TList *AliAnalysisVertexingHF::FillListOfCuts() {
354 // Fill list of analysis cuts
356 TList *list = new TList();
358 list->SetName("ListOfCuts");
361 AliRDHFCutsD0toKpi *cutsD0toKpi = new AliRDHFCutsD0toKpi(*fCutsD0toKpi);
362 list->Add(cutsD0toKpi);
365 AliRDHFCutsJpsitoee *cutsJpsitoee = new AliRDHFCutsJpsitoee(*fCutsJpsitoee);
366 list->Add(cutsJpsitoee);
368 if(fCutsDplustoKpipi) {
369 AliRDHFCutsDplustoKpipi *cutsDplustoKpipi = new AliRDHFCutsDplustoKpipi(*fCutsDplustoKpipi);
370 list->Add(cutsDplustoKpipi);
373 AliRDHFCutsDstoKKpi *cutsDstoKKpi = new AliRDHFCutsDstoKKpi(*fCutsDstoKKpi);
374 list->Add(cutsDstoKKpi);
377 AliRDHFCutsLctopKpi *cutsLctopKpi = new AliRDHFCutsLctopKpi(*fCutsLctopKpi);
378 list->Add(cutsLctopKpi);
381 AliRDHFCutsLctoV0 *cutsLctoV0 = new AliRDHFCutsLctoV0(*fCutsLctoV0);
382 list->Add(cutsLctoV0);
384 if(fCutsD0toKpipipi) {
385 AliRDHFCutsD0toKpipipi *cutsD0toKpipipi = new AliRDHFCutsD0toKpipipi(*fCutsD0toKpipipi);
386 list->Add(cutsD0toKpipipi);
388 if(fCutsDStartoKpipi) {
389 AliRDHFCutsDStartoKpipi *cutsDStartoKpipi = new AliRDHFCutsDStartoKpipi(*fCutsDStartoKpipi);
390 list->Add(cutsDStartoKpipi);
393 //___ Check consitstency of cuts between vertexer and analysis tasks
394 Bool_t bCutsOk = CheckCutsConsistency();
395 if (bCutsOk == kFALSE) {AliFatal("AliAnalysisVertexingHF::FillListOfCuts vertexing and the analysis task cuts are not consistent!");}
397 // keep a pointer to the list
402 //----------------------------------------------------------------------------
403 void AliAnalysisVertexingHF::FindCandidates(AliVEvent *event,
404 TClonesArray *aodVerticesHFTClArr,
405 TClonesArray *aodD0toKpiTClArr,
406 TClonesArray *aodJPSItoEleTClArr,
407 TClonesArray *aodCharm3ProngTClArr,
408 TClonesArray *aodCharm4ProngTClArr,
409 TClonesArray *aodDstarTClArr,
410 TClonesArray *aodCascadesTClArr,
411 TClonesArray *aodLikeSign2ProngTClArr,
412 TClonesArray *aodLikeSign3ProngTClArr)
414 // Find heavy-flavour vertex candidates
416 // Output: AOD (additional branches added)
417 //AliCodeTimerAuto("",0);
420 TString evtype = event->IsA()->GetName();
421 fInputAOD = ((evtype=="AliAODEvent") ? kTRUE : kFALSE);
422 } // if we do mixing AliVEvent is a AliMixedEvent
425 AliDebug(2,"Creating HF candidates from AOD");
427 AliDebug(2,"Creating HF candidates from ESD");
430 if(!aodVerticesHFTClArr) {
431 printf("ERROR: no aodVerticesHFTClArr");
434 if((fD0toKpi || fDstar) && !aodD0toKpiTClArr) {
435 printf("ERROR: no aodD0toKpiTClArr");
438 if(fJPSItoEle && !aodJPSItoEleTClArr) {
439 printf("ERROR: no aodJPSItoEleTClArr");
442 if(f3Prong && !aodCharm3ProngTClArr) {
443 printf("ERROR: no aodCharm3ProngTClArr");
446 if(f4Prong && !aodCharm4ProngTClArr) {
447 printf("ERROR: no aodCharm4ProngTClArr");
450 if(fDstar && !aodDstarTClArr) {
451 printf("ERROR: no aodDstarTClArr");
454 if(fCascades && !aodCascadesTClArr){
455 printf("ERROR: no aodCascadesTClArr ");
458 if(fLikeSign && !aodLikeSign2ProngTClArr) {
459 printf("ERROR: no aodLikeSign2ProngTClArr");
462 if(fLikeSign3prong && f3Prong && !aodLikeSign3ProngTClArr) {
463 printf("ERROR: no aodLikeSign3ProngTClArr");
467 // delete candidates from previous event and create references
468 Int_t iVerticesHF=0,iD0toKpi=0,iJPSItoEle=0,i3Prong=0,i4Prong=0,iDstar=0,iCascades=0,iLikeSign2Prong=0,iLikeSign3Prong=0;
469 aodVerticesHFTClArr->Delete();
470 iVerticesHF = aodVerticesHFTClArr->GetEntriesFast();
471 TClonesArray &verticesHFRef = *aodVerticesHFTClArr;
472 if(fD0toKpi || fDstar) {
473 aodD0toKpiTClArr->Delete();
474 iD0toKpi = aodD0toKpiTClArr->GetEntriesFast();
477 aodJPSItoEleTClArr->Delete();
478 iJPSItoEle = aodJPSItoEleTClArr->GetEntriesFast();
481 aodCharm3ProngTClArr->Delete();
482 i3Prong = aodCharm3ProngTClArr->GetEntriesFast();
485 aodCharm4ProngTClArr->Delete();
486 i4Prong = aodCharm4ProngTClArr->GetEntriesFast();
489 aodDstarTClArr->Delete();
490 iDstar = aodDstarTClArr->GetEntriesFast();
493 aodCascadesTClArr->Delete();
494 iCascades = aodCascadesTClArr->GetEntriesFast();
497 aodLikeSign2ProngTClArr->Delete();
498 iLikeSign2Prong = aodLikeSign2ProngTClArr->GetEntriesFast();
500 if(fLikeSign3prong && f3Prong) {
501 aodLikeSign3ProngTClArr->Delete();
502 iLikeSign3Prong = aodLikeSign3ProngTClArr->GetEntriesFast();
505 TClonesArray &aodD0toKpiRef = *aodD0toKpiTClArr;
506 TClonesArray &aodJPSItoEleRef = *aodJPSItoEleTClArr;
507 TClonesArray &aodCharm3ProngRef = *aodCharm3ProngTClArr;
508 TClonesArray &aodCharm4ProngRef = *aodCharm4ProngTClArr;
509 TClonesArray &aodDstarRef = *aodDstarTClArr;
510 TClonesArray &aodCascadesRef = *aodCascadesTClArr;
511 TClonesArray &aodLikeSign2ProngRef = *aodLikeSign2ProngTClArr;
512 TClonesArray &aodLikeSign3ProngRef = *aodLikeSign3ProngTClArr;
515 AliAODRecoDecayHF2Prong *io2Prong = 0;
516 AliAODRecoDecayHF3Prong *io3Prong = 0;
517 AliAODRecoDecayHF4Prong *io4Prong = 0;
518 AliAODRecoCascadeHF *ioCascade = 0;
520 Int_t iTrkP1,iTrkP2,iTrkN1,iTrkN2,iTrkSoftPi,trkEntries,iv0,nv0;
521 Double_t xdummy,ydummy,dcap1n1,dcap1n2,dcap2n1,dcap1p2,dcan1n2,dcap2n2,dcaV0,dcaCasc;
522 Bool_t okD0=kFALSE,okJPSI=kFALSE,ok3Prong=kFALSE,ok4Prong=kFALSE;
523 Bool_t okDstar=kFALSE,okD0fromDstar=kFALSE;
524 Bool_t okCascades=kFALSE;
525 AliESDtrack *postrack1 = 0;
526 AliESDtrack *postrack2 = 0;
527 AliESDtrack *negtrack1 = 0;
528 AliESDtrack *negtrack2 = 0;
529 AliESDtrack *trackPi = 0;
530 Double_t mompos1[3],mompos2[3],momneg1[3],momneg2[3];
531 // AliESDtrack *posV0track = 0;
532 // AliESDtrack *negV0track = 0;
533 Float_t dcaMax = fCutsD0toKpi->GetDCACut();
534 if(fCutsJpsitoee) dcaMax=TMath::Max(dcaMax,fCutsJpsitoee->GetDCACut());
535 if(fCutsDplustoKpipi) dcaMax=TMath::Max(dcaMax,fCutsDplustoKpipi->GetDCACut());
536 if(fCutsDstoKKpi) dcaMax=TMath::Max(dcaMax,fCutsDstoKKpi->GetDCACut());
537 if(fCutsLctopKpi) dcaMax=TMath::Max(dcaMax,fCutsLctopKpi->GetDCACut());
538 if(fCutsD0toKpipipi) dcaMax=TMath::Max(dcaMax,fCutsD0toKpipipi->GetDCACut());
539 if(fCutsDStartoKpipi) dcaMax=TMath::Max(dcaMax,fCutsDStartoKpipi->GetDCACut());
541 AliDebug(2,Form(" dca cut set to %f cm",dcaMax));
545 fBzkG = (Double_t)event->GetMagneticField();
546 if(!fVertexerTracks){
547 fVertexerTracks=new AliVertexerTracks(fBzkG);
549 Double_t oldField=fVertexerTracks->GetFieldkG();
550 if(oldField!=fBzkG) fVertexerTracks->SetFieldkG(fBzkG);
553 trkEntries = (Int_t)event->GetNumberOfTracks();
554 AliDebug(1,Form(" Number of tracks: %d",trkEntries));
555 fnTrksTotal += trkEntries;
557 nv0 = (Int_t)event->GetNumberOfV0s();
558 AliDebug(1,Form(" Number of V0s: %d",nv0));
560 if( trkEntries<2 && (trkEntries<1 || nv0<1) ) {
561 AliDebug(1,Form(" Not enough tracks: %d",trkEntries));
565 // event selection + PID configuration
566 if(!fCutsD0toKpi->IsEventSelected(event)) return;
567 if(fCutsJpsitoee) fCutsJpsitoee->SetupPID(event);
568 if(fCutsDplustoKpipi) fCutsDplustoKpipi->SetupPID(event);
569 if(fCutsDstoKKpi) fCutsDstoKKpi->SetupPID(event);
570 if(fCutsLctopKpi) fCutsLctopKpi->SetupPID(event);
571 if(fCutsLctoV0) fCutsLctoV0->SetupPID(event);
572 if(fCutsD0toKpipipi) fCutsD0toKpipipi->SetupPID(event);
573 if(fCutsDStartoKpipi) fCutsDStartoKpipi->SetupPID(event);
575 // call function that applies sigle-track selection,
576 // for displaced tracks and soft pions (both charges) for D*,
577 // and retrieves primary vertex
578 TObjArray seleTrksArray(trkEntries);
579 TObjArray tracksAtVertex(trkEntries);
580 UChar_t *seleFlags = new UChar_t[trkEntries]; // bit 0: displaced, bit 1: softpi, bit 2: 3 prong, bits 3-4-5: for PID
582 Int_t *evtNumber = new Int_t[trkEntries];
583 SelectTracksAndCopyVertex(event,trkEntries,seleTrksArray,tracksAtVertex,nSeleTrks,seleFlags,evtNumber);
585 AliDebug(1,Form(" Selected tracks: %d",nSeleTrks));
586 fnSeleTrksTotal += nSeleTrks;
589 TObjArray *twoTrackArray1 = new TObjArray(2);
590 TObjArray *twoTrackArray2 = new TObjArray(2);
591 TObjArray *twoTrackArrayV0 = new TObjArray(2);
592 TObjArray *twoTrackArrayCasc = new TObjArray(2);
593 TObjArray *threeTrackArray = new TObjArray(3);
594 TObjArray *fourTrackArray = new TObjArray(4);
597 Bool_t isLikeSign2Prong=kFALSE,isLikeSign3Prong=kFALSE;
599 AliAODRecoDecayHF *rd = 0;
600 AliAODRecoCascadeHF *rc = 0;
604 Bool_t massCutOK=kTRUE;
606 // LOOP ON POSITIVE TRACKS
607 for(iTrkP1=0; iTrkP1<nSeleTrks; iTrkP1++) {
609 //if(iTrkP1%1==0) AliDebug(1,Form(" 1st loop on pos: track number %d of %d",iTrkP1,nSeleTrks));
610 //if(iTrkP1%1==0) printf(" 1st loop on pos: track number %d of %d\n",iTrkP1,nSeleTrks);
612 // get track from tracks array
613 postrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP1);
614 if(!TESTBIT(seleFlags[iTrkP1],kBitDispl)) continue;
615 postrack1->GetPxPyPz(mompos1);
617 // Make cascades with V0+track
621 for(iv0=0; iv0<nv0; iv0++){
623 //AliDebug(1,Form(" loop on v0s for track number %d and v0 number %d",iTrkP1,iv0));
625 if ( fUsePIDforLc2V0 && !TESTBIT(seleFlags[iTrkP1],kBitProtonCompat) ) continue; //clm
629 v0 = ((AliAODEvent*)event)->GetV0(iv0);
631 esdV0 = ((AliESDEvent*)event)->GetV0(iv0);
633 if ( (!v0 || !v0->IsA()->InheritsFrom("AliAODv0") ) &&
634 (!esdV0 || !esdV0->IsA()->InheritsFrom("AliESDv0") ) ) continue;
636 if ( v0 && ((v0->GetOnFlyStatus() == kTRUE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOfflineV0s) ||
637 (v0->GetOnFlyStatus() == kFALSE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOnTheFlyV0s)) ) continue;
639 if ( esdV0 && ((esdV0->GetOnFlyStatus() == kTRUE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOfflineV0s) ||
640 ( esdV0->GetOnFlyStatus() == kFALSE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOnTheFlyV0s)) ) continue;
642 // Get the tracks that form the V0
643 // ( parameters at primary vertex )
644 // and define an AliExternalTrackParam out of them
645 AliExternalTrackParam * posV0track;
646 AliExternalTrackParam * negV0track;
649 AliAODTrack *posVV0track = (AliAODTrack*)(v0->GetDaughter(0));
650 AliAODTrack *negVV0track = (AliAODTrack*)(v0->GetDaughter(1));
651 if( !posVV0track || !negVV0track ) continue;
653 // Apply some basic V0 daughter criteria
655 // bachelor must not be a v0-track
656 if (posVV0track->GetID() == postrack1->GetID() ||
657 negVV0track->GetID() == postrack1->GetID()) continue;
658 // reject like-sign v0
659 if ( posVV0track->Charge() == negVV0track->Charge() ) continue;
660 // avoid ghost TPC tracks
661 if(!(posVV0track->GetStatus() & AliESDtrack::kTPCrefit) ||
662 !(negVV0track->GetStatus() & AliESDtrack::kTPCrefit)) continue;
663 // Get AliExternalTrackParam out of the AliAODTracks
664 Double_t xyz[3], pxpypz[3], cv[21]; Short_t sign;
665 posVV0track->PxPyPz(pxpypz); posVV0track->XvYvZv(xyz);
666 posVV0track->GetCovarianceXYZPxPyPz(cv); sign=posVV0track->Charge();
667 posV0track = new AliExternalTrackParam(xyz,pxpypz,cv,sign);
668 negVV0track->PxPyPz(pxpypz); negVV0track->XvYvZv(xyz);
669 negVV0track->GetCovarianceXYZPxPyPz(cv); sign=negVV0track->Charge();
670 negV0track = new AliExternalTrackParam(xyz,pxpypz,cv,sign);
672 AliESDtrack *posVV0track = (AliESDtrack*)(event->GetTrack( esdV0->GetPindex() ));
673 AliESDtrack *negVV0track = (AliESDtrack*)(event->GetTrack( esdV0->GetNindex() ));
674 if( !posVV0track || !negVV0track ) continue;
676 // Apply some basic V0 daughter criteria
678 // bachelor must not be a v0-track
679 if (posVV0track->GetID() == postrack1->GetID() ||
680 negVV0track->GetID() == postrack1->GetID()) continue;
681 // reject like-sign v0
682 if ( posVV0track->Charge() == negVV0track->Charge() ) continue;
683 // avoid ghost TPC tracks
684 if(!(posVV0track->GetStatus() & AliESDtrack::kTPCrefit) ||
685 !(negVV0track->GetStatus() & AliESDtrack::kTPCrefit)) continue;
686 // reject kinks (only necessary on AliESDtracks)
687 if (posVV0track->GetKinkIndex(0)>0 || negVV0track->GetKinkIndex(0)>0) continue;
688 // Get AliExternalTrackParam out of the AliESDtracks
689 posV0track = new AliExternalTrackParam(*posVV0track);
690 negV0track = new AliExternalTrackParam(*negVV0track);
692 // Define the AODv0 from ESDv0 if reading ESDs
693 v0 = TransformESDv0toAODv0(esdV0,twoTrackArrayV0);
695 if( !posV0track || !negV0track ){
696 AliDebug(1,Form(" Couldn't get the V0 daughters"));
700 // fill in the v0 two-external-track-param array
701 twoTrackArrayV0->AddAt(posV0track,0);
702 twoTrackArrayV0->AddAt(negV0track,1);
705 dcaV0 = v0->DcaV0Daughters();
707 // Define the V0 (neutral) track
708 AliNeutralTrackParam *trackV0;
710 const AliVTrack *trackVV0 = dynamic_cast<const AliVTrack*>(v0);
711 if(trackVV0) trackV0 = new AliNeutralTrackParam(trackVV0);
713 Double_t xyz[3], pxpypz[3];
715 esdV0->PxPyPz(pxpypz);
716 Double_t cv[21]; for(int i=0; i<21; i++) cv[i]=0;
717 trackV0 = new AliNeutralTrackParam(xyz,pxpypz,cv,0);
719 // Fill in the object array to create the cascade
720 twoTrackArrayCasc->AddAt(postrack1,0);
721 twoTrackArrayCasc->AddAt(trackV0,1);
722 // Compute the cascade vertex
723 AliAODVertex *vertexCasc = 0;
724 if(fFindVertexForCascades) {
725 // DCA between the two tracks
726 dcaCasc = postrack1->GetDCA(trackV0,fBzkG,xdummy,ydummy);
728 vertexCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
730 // assume Cascade decays at the primary vertex
731 Double_t pos[3],cov[6],chi2perNDF;
733 fV1->GetCovMatrix(cov);
734 chi2perNDF = fV1->GetChi2toNDF();
735 vertexCasc = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,2);
739 delete posV0track; posV0track=NULL;
740 delete negV0track; negV0track=NULL;
741 delete trackV0; trackV0=NULL;
742 if(!fInputAOD) {delete v0; v0=NULL;}
743 twoTrackArrayV0->Clear();
744 twoTrackArrayCasc->Clear();
748 // Create and store the Cascade if passed the cuts
749 ioCascade = MakeCascade(twoTrackArrayCasc,event,vertexCasc,v0,dcaCasc,okCascades);
750 if(okCascades && ioCascade) {
751 //AliDebug(1,Form("Storing a cascade object... "));
752 // add the vertex and the cascade to the AOD
753 AliAODVertex *vCasc = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexCasc);
754 rc = new(aodCascadesRef[iCascades++])AliAODRecoCascadeHF(*ioCascade);
755 rc->SetSecondaryVtx(vCasc);
756 vCasc->SetParent(rc);
757 rc->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
758 if(!fInputAOD) vCasc->AddDaughter(v0); // just to fill ref #0 ??
759 AddRefs(vCasc,rc,event,twoTrackArrayCasc); // add the track (proton)
760 vCasc->AddDaughter(v0); // fill the 2prong V0
764 delete posV0track; posV0track=NULL;
765 delete negV0track; negV0track=NULL;
766 delete trackV0; trackV0=NULL;
767 twoTrackArrayV0->Clear();
768 twoTrackArrayCasc->Clear();
769 if(ioCascade) { delete ioCascade; ioCascade=NULL; }
770 if(vertexCasc) { delete vertexCasc; vertexCasc=NULL; }
771 if(!fInputAOD) {delete v0; v0=NULL;}
773 } // end loop on V0's
776 // If there is less than 2 particles continue
778 AliDebug(1,Form(" Not enough tracks: %d",trkEntries));
782 if(postrack1->Charge()<0 && !fLikeSign) continue;
784 // LOOP ON NEGATIVE TRACKS
785 for(iTrkN1=0; iTrkN1<nSeleTrks; iTrkN1++) {
787 //if(iTrkN1%1==0) AliDebug(1,Form(" 1st loop on neg: track number %d of %d",iTrkN1,nSeleTrks));
788 //if(iTrkN1%1==0) printf(" 1st loop on neg: track number %d of %d\n",iTrkN1,nSeleTrks);
790 if(iTrkN1==iTrkP1) continue;
792 // get track from tracks array
793 negtrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN1);
795 if(negtrack1->Charge()>0 && !fLikeSign) continue;
797 if(!TESTBIT(seleFlags[iTrkN1],kBitDispl)) continue;
800 if(evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
803 if(postrack1->Charge()==negtrack1->Charge()) { // like-sign
804 isLikeSign2Prong=kTRUE;
805 if(!fLikeSign) continue;
806 if(iTrkN1<iTrkP1) continue; // this is needed to avoid double-counting of like-sign
807 } else { // unlike-sign
808 isLikeSign2Prong=kFALSE;
809 if(postrack1->Charge()<0 || negtrack1->Charge()>0) continue; // this is needed to avoid double-counting of unlike-sign
811 if(evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
816 // back to primary vertex
817 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
818 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
819 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
820 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
821 negtrack1->GetPxPyPz(momneg1);
823 // DCA between the two tracks
824 dcap1n1 = postrack1->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
825 if(dcap1n1>dcaMax) { negtrack1=0; continue; }
828 twoTrackArray1->AddAt(postrack1,0);
829 twoTrackArray1->AddAt(negtrack1,1);
830 AliAODVertex *vertexp1n1 = ReconstructSecondaryVertex(twoTrackArray1,dispersion);
832 twoTrackArray1->Clear();
838 if(fD0toKpi || fJPSItoEle || fDstar || fLikeSign) {
840 io2Prong = Make2Prong(twoTrackArray1,event,vertexp1n1,dcap1n1,okD0,okJPSI,okD0fromDstar);
842 if((fD0toKpi && okD0) || (fJPSItoEle && okJPSI) || (isLikeSign2Prong && (okD0 || okJPSI))) {
843 // add the vertex and the decay to the AOD
844 AliAODVertex *v2Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
845 if(!isLikeSign2Prong) {
847 rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
848 rd->SetSecondaryVtx(v2Prong);
849 v2Prong->SetParent(rd);
850 AddRefs(v2Prong,rd,event,twoTrackArray1);
853 rd = new(aodJPSItoEleRef[iJPSItoEle++])AliAODRecoDecayHF2Prong(*io2Prong);
854 rd->SetSecondaryVtx(v2Prong);
855 if(!okD0) v2Prong->SetParent(rd); // it cannot have two mothers ...
856 AddRefs(v2Prong,rd,event,twoTrackArray1);
858 } else { // isLikeSign2Prong
859 rd = new(aodLikeSign2ProngRef[iLikeSign2Prong++])AliAODRecoDecayHF2Prong(*io2Prong);
860 rd->SetSecondaryVtx(v2Prong);
861 v2Prong->SetParent(rd);
862 AddRefs(v2Prong,rd,event,twoTrackArray1);
864 // Set selection bit for PID
865 if(okD0) SetSelectionBitForPID(fCutsD0toKpi,rd,AliRDHFCuts::kD0toKpiPID);
868 if(fDstar && okD0fromDstar && !isLikeSign2Prong) {
869 // write references in io2Prong
871 AddDaughterRefs(vertexp1n1,event,twoTrackArray1);
873 vertexp1n1->AddDaughter(postrack1);
874 vertexp1n1->AddDaughter(negtrack1);
876 io2Prong->SetSecondaryVtx(vertexp1n1);
877 //printf("---> %d %d %d %d %d\n",vertexp1n1->GetNDaughters(),iTrkP1,iTrkN1,postrack1->Charge(),negtrack1->Charge());
878 // create a track from the D0
879 AliNeutralTrackParam *trackD0 = new AliNeutralTrackParam(io2Prong);
881 // LOOP ON TRACKS THAT PASSED THE SOFT PION CUTS
882 for(iTrkSoftPi=0; iTrkSoftPi<nSeleTrks; iTrkSoftPi++) {
884 if(iTrkSoftPi==iTrkP1 || iTrkSoftPi==iTrkN1) continue;
886 if(!TESTBIT(seleFlags[iTrkSoftPi],kBitSoftPi)) continue;
889 if(evtNumber[iTrkP1]==evtNumber[iTrkSoftPi] ||
890 evtNumber[iTrkN1]==evtNumber[iTrkSoftPi] ||
891 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
894 //if(iTrkSoftPi%1==0) AliDebug(1,Form(" 1st loop on pi_s: track number %d of %d",iTrkSoftPi,nSeleTrks));
896 trackD0->PropagateToDCA(fV1,fBzkG,kVeryBig);
897 if(trackD0->GetSigmaY2()<0. || trackD0->GetSigmaZ2()<0.) continue; // this is insipired by the AliITStrackV2::Invariant() checks
899 // get track from tracks array
900 trackPi = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkSoftPi);
901 // trackPi->PropagateToDCA(fV1,fBzkG,kVeryBig);
902 SetParametersAtVertex(trackPi,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkSoftPi));
903 twoTrackArrayCasc->AddAt(trackPi,0);
904 twoTrackArrayCasc->AddAt(trackD0,1);
905 if(!SelectInvMassAndPtDstarD0pi(twoTrackArrayCasc)){
906 twoTrackArrayCasc->Clear();
911 AliAODVertex *vertexCasc = 0;
913 if(fFindVertexForDstar) {
914 // DCA between the two tracks
915 dcaCasc = trackPi->GetDCA(trackD0,fBzkG,xdummy,ydummy);
917 vertexCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
919 // assume Dstar decays at the primary vertex
920 Double_t pos[3],cov[6],chi2perNDF;
922 fV1->GetCovMatrix(cov);
923 chi2perNDF = fV1->GetChi2toNDF();
924 vertexCasc = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,2);
928 twoTrackArrayCasc->Clear();
933 ioCascade = MakeCascade(twoTrackArrayCasc,event,vertexCasc,io2Prong,dcaCasc,okDstar);
935 // add the D0 to the AOD (if not already done)
937 AliAODVertex *v2Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
938 rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
939 rd->SetSecondaryVtx(v2Prong);
940 v2Prong->SetParent(rd);
941 AddRefs(v2Prong,rd,event,twoTrackArray1);
942 okD0=kTRUE; // this is done to add it only once
944 // add the vertex and the cascade to the AOD
945 AliAODVertex *vCasc = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexCasc);
946 rc = new(aodDstarRef[iDstar++])AliAODRecoCascadeHF(*ioCascade);
947 rc->SetSecondaryVtx(vCasc);
948 vCasc->SetParent(rc);
949 if(!fInputAOD) vCasc->AddDaughter(rd); // just to fill ref #0
950 AddRefs(vCasc,rc,event,twoTrackArrayCasc);
951 vCasc->AddDaughter(rd); // add the D0 (in ref #1)
952 // Set selection bit for PID
953 SetSelectionBitForPID(fCutsDStartoKpipi,rc,AliRDHFCuts::kDstarPID);
955 twoTrackArrayCasc->Clear();
957 if(ioCascade) {delete ioCascade; ioCascade=NULL;}
958 delete vertexCasc; vertexCasc=NULL;
959 } // end loop on soft pi tracks
961 if(trackD0) {delete trackD0; trackD0=NULL;}
964 if(io2Prong) {delete io2Prong; io2Prong=NULL;}
967 twoTrackArray1->Clear();
968 if( (!f3Prong && !f4Prong) ||
969 (isLikeSign2Prong && !f3Prong) ) {
976 // 2nd LOOP ON POSITIVE TRACKS
977 for(iTrkP2=iTrkP1+1; iTrkP2<nSeleTrks; iTrkP2++) {
979 if(iTrkP2==iTrkP1 || iTrkP2==iTrkN1) continue;
981 //if(iTrkP2%1==0) AliDebug(1,Form(" 2nd loop on pos: track number %d of %d",iTrkP2,nSeleTrks));
983 // get track from tracks array
984 postrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP2);
986 if(postrack2->Charge()<0) continue;
988 if(!TESTBIT(seleFlags[iTrkP2],kBitDispl)) continue;
990 // Check single tracks cuts specific for 3 prongs
991 if(!TESTBIT(seleFlags[iTrkP2],kBit3Prong)) continue;
992 if(!TESTBIT(seleFlags[iTrkP1],kBit3Prong)) continue;
993 if(!TESTBIT(seleFlags[iTrkN1],kBit3Prong)) continue;
996 if(evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
997 evtNumber[iTrkN1]==evtNumber[iTrkP2] ||
998 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
1001 if(isLikeSign2Prong) { // like-sign pair -> have to build only like-sign triplet
1002 if(!fLikeSign3prong) continue;
1003 if(postrack1->Charge()>0) { // ok: like-sign triplet (+++)
1004 isLikeSign3Prong=kTRUE;
1008 } else { // normal triplet (+-+)
1009 isLikeSign3Prong=kFALSE;
1011 if(evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
1012 evtNumber[iTrkN1]==evtNumber[iTrkP2] ||
1013 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
1017 if(fUseKaonPIDfor3Prong){
1018 if(!TESTBIT(seleFlags[iTrkN1],kBitKaonCompat)) continue;
1020 Bool_t okForLcTopKpi=kTRUE;
1021 Int_t pidLcStatus=3; // 3= OK as pKpi and Kpipi
1023 if(!TESTBIT(seleFlags[iTrkP1],kBitProtonCompat) &&
1024 !TESTBIT(seleFlags[iTrkP2],kBitProtonCompat) ){
1025 okForLcTopKpi=kFALSE;
1028 if(okForLcTopKpi && fUsePIDforLc>1){
1029 okForLcTopKpi=kFALSE;
1031 if(TESTBIT(seleFlags[iTrkP1],kBitProtonCompat) &&
1032 TESTBIT(seleFlags[iTrkP2],kBitPionCompat) ){
1033 okForLcTopKpi=kTRUE;
1034 pidLcStatus+=1; // 1= OK as pKpi
1036 if(TESTBIT(seleFlags[iTrkP2],kBitProtonCompat) &&
1037 TESTBIT(seleFlags[iTrkP1],kBitPionCompat) ){
1038 okForLcTopKpi=kTRUE;
1039 pidLcStatus+=2; // 2= OK as piKp
1043 Bool_t okForDsToKKpi=kTRUE;
1044 if(fUseKaonPIDforDs){
1045 if(!TESTBIT(seleFlags[iTrkP1],kBitKaonCompat) &&
1046 !TESTBIT(seleFlags[iTrkP2],kBitKaonCompat) ) okForDsToKKpi=kFALSE;
1048 // back to primary vertex
1049 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1050 // postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1051 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1052 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1053 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1054 SetParametersAtVertex(postrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP2));
1056 //printf("********** %d %d %d\n",postrack1->GetID(),postrack2->GetID(),negtrack1->GetID());
1058 dcap2n1 = postrack2->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
1059 if(dcap2n1>dcaMax) { postrack2=0; continue; }
1060 dcap1p2 = postrack2->GetDCA(postrack1,fBzkG,xdummy,ydummy);
1061 if(dcap1p2>dcaMax) { postrack2=0; continue; }
1063 // check invariant mass cuts for D+,Ds,Lc
1066 if(postrack2->Charge()>0) {
1067 threeTrackArray->AddAt(postrack1,0);
1068 threeTrackArray->AddAt(negtrack1,1);
1069 threeTrackArray->AddAt(postrack2,2);
1071 threeTrackArray->AddAt(negtrack1,0);
1072 threeTrackArray->AddAt(postrack1,1);
1073 threeTrackArray->AddAt(postrack2,2);
1075 if(fMassCutBeforeVertexing){
1076 postrack2->GetPxPyPz(mompos2);
1077 Double_t pxDau[3]={mompos1[0],momneg1[0],mompos2[0]};
1078 Double_t pyDau[3]={mompos1[1],momneg1[1],mompos2[1]};
1079 Double_t pzDau[3]={mompos1[2],momneg1[2],mompos2[2]};
1080 // massCutOK = SelectInvMassAndPt3prong(threeTrackArray);
1081 massCutOK = SelectInvMassAndPt3prong(pxDau,pyDau,pzDau,pidLcStatus);
1085 if(f3Prong && !massCutOK) {
1086 threeTrackArray->Clear();
1094 twoTrackArray2->AddAt(postrack2,0);
1095 twoTrackArray2->AddAt(negtrack1,1);
1096 AliAODVertex *vertexp2n1 = ReconstructSecondaryVertex(twoTrackArray2,dispersion);
1098 twoTrackArray2->Clear();
1103 // 3 prong candidates
1104 if(f3Prong && massCutOK) {
1106 AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1107 io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,vertexp2n1,dcap1n1,dcap2n1,dcap1p2,okForLcTopKpi,okForDsToKKpi,ok3Prong);
1109 AliAODVertex *v3Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
1110 if(!isLikeSign3Prong) {
1111 rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1112 rd->SetSecondaryVtx(v3Prong);
1113 v3Prong->SetParent(rd);
1114 AddRefs(v3Prong,rd,event,threeTrackArray);
1115 } else { // isLikeSign3Prong
1116 if(fLikeSign3prong){
1117 rd = new(aodLikeSign3ProngRef[iLikeSign3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1118 rd->SetSecondaryVtx(v3Prong);
1119 v3Prong->SetParent(rd);
1120 AddRefs(v3Prong,rd,event,threeTrackArray);
1123 // Set selection bit for PID
1124 SetSelectionBitForPID(fCutsDplustoKpipi,rd,AliRDHFCuts::kDplusPID);
1125 SetSelectionBitForPID(fCutsDstoKKpi,rd,AliRDHFCuts::kDsPID);
1126 SetSelectionBitForPID(fCutsLctopKpi,rd,AliRDHFCuts::kLcPID);
1128 if(io3Prong) {delete io3Prong; io3Prong=NULL;}
1129 if(secVert3PrAOD) {delete secVert3PrAOD; secVert3PrAOD=NULL;}
1132 // 4 prong candidates
1134 // don't make 4 prong with like-sign pairs and triplets
1135 && !isLikeSign2Prong && !isLikeSign3Prong
1136 // track-to-track dca cuts already now
1137 && dcap1n1 < fCutsD0toKpipipi->GetDCACut()
1138 && dcap2n1 < fCutsD0toKpipipi->GetDCACut()) {
1140 // back to primary vertex
1141 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1142 // postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1143 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1144 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1145 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1146 SetParametersAtVertex(postrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP2));
1148 // Vertexing for these 3 (can be taken from above?)
1149 threeTrackArray->AddAt(postrack1,0);
1150 threeTrackArray->AddAt(negtrack1,1);
1151 threeTrackArray->AddAt(postrack2,2);
1152 AliAODVertex* vertexp1n1p2 = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1154 // 3rd LOOP ON NEGATIVE TRACKS (for 4 prong)
1155 for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
1157 if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
1159 //if(iTrkN2%1==0) AliDebug(1,Form(" 3rd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));
1161 // get track from tracks array
1162 negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
1164 if(negtrack2->Charge()>0) continue;
1166 if(!TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
1168 if(evtNumber[iTrkP1]==evtNumber[iTrkN2] ||
1169 evtNumber[iTrkN1]==evtNumber[iTrkN2] ||
1170 evtNumber[iTrkP2]==evtNumber[iTrkN2] ||
1171 evtNumber[iTrkP1]==evtNumber[iTrkN1] ||
1172 evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
1173 evtNumber[iTrkN1]==evtNumber[iTrkP2]) continue;
1176 // back to primary vertex
1177 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1178 // postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1179 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1180 // negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1181 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1182 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1183 SetParametersAtVertex(postrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP2));
1184 SetParametersAtVertex(negtrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN2));
1186 dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1187 if(dcap1n2 > fCutsD0toKpipipi->GetDCACut()) { negtrack2=0; continue; }
1188 dcap2n2 = postrack2->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1189 if(dcap2n2 > fCutsD0toKpipipi->GetDCACut()) { negtrack2=0; continue; }
1192 fourTrackArray->AddAt(postrack1,0);
1193 fourTrackArray->AddAt(negtrack1,1);
1194 fourTrackArray->AddAt(postrack2,2);
1195 fourTrackArray->AddAt(negtrack2,3);
1197 // check invariant mass cuts for D0
1199 if(fMassCutBeforeVertexing)
1200 massCutOK = SelectInvMassAndPt4prong(fourTrackArray);
1203 fourTrackArray->Clear();
1209 AliAODVertex* secVert4PrAOD = ReconstructSecondaryVertex(fourTrackArray,dispersion);
1210 io4Prong = Make4Prong(fourTrackArray,event,secVert4PrAOD,vertexp1n1,vertexp1n1p2,dcap1n1,dcap1n2,dcap2n1,dcap2n2,ok4Prong);
1212 AliAODVertex *v4Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert4PrAOD);
1213 rd = new(aodCharm4ProngRef[i4Prong++])AliAODRecoDecayHF4Prong(*io4Prong);
1214 rd->SetSecondaryVtx(v4Prong);
1215 v4Prong->SetParent(rd);
1216 AddRefs(v4Prong,rd,event,fourTrackArray);
1219 if(io4Prong) {delete io4Prong; io4Prong=NULL;}
1220 if(secVert4PrAOD) {delete secVert4PrAOD; secVert4PrAOD=NULL;}
1221 fourTrackArray->Clear();
1224 } // end loop on negative tracks
1226 threeTrackArray->Clear();
1227 delete vertexp1n1p2;
1234 } // end 2nd loop on positive tracks
1236 twoTrackArray2->Clear();
1238 // 2nd LOOP ON NEGATIVE TRACKS (for 3 prong -+-)
1239 for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
1241 if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
1243 //if(iTrkN2%1==0) AliDebug(1,Form(" 2nd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));
1245 // get track from tracks array
1246 negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
1248 if(negtrack2->Charge()>0) continue;
1250 if(!TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
1252 // Check single tracks cuts specific for 3 prongs
1253 if(!TESTBIT(seleFlags[iTrkN2],kBit3Prong)) continue;
1254 if(!TESTBIT(seleFlags[iTrkP1],kBit3Prong)) continue;
1255 if(!TESTBIT(seleFlags[iTrkN1],kBit3Prong)) continue;
1258 if(evtNumber[iTrkP1]==evtNumber[iTrkN2] ||
1259 evtNumber[iTrkN1]==evtNumber[iTrkN2] ||
1260 evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
1263 if(isLikeSign2Prong) { // like-sign pair -> have to build only like-sign triplet
1264 if(!fLikeSign3prong) continue;
1265 if(postrack1->Charge()<0) { // ok: like-sign triplet (---)
1266 isLikeSign3Prong=kTRUE;
1270 } else { // normal triplet (-+-)
1271 isLikeSign3Prong=kFALSE;
1274 if(fUseKaonPIDfor3Prong){
1275 if(!TESTBIT(seleFlags[iTrkP1],kBitKaonCompat)) continue;
1277 Bool_t okForLcTopKpi=kTRUE;
1278 Int_t pidLcStatus=3; // 3= OK as pKpi and Kpipi
1280 if(!TESTBIT(seleFlags[iTrkN1],kBitProtonCompat) &&
1281 !TESTBIT(seleFlags[iTrkN2],kBitProtonCompat) ){
1282 okForLcTopKpi=kFALSE;
1285 if(okForLcTopKpi && fUsePIDforLc>1){
1286 okForLcTopKpi=kFALSE;
1288 if(TESTBIT(seleFlags[iTrkN1],kBitProtonCompat) &&
1289 TESTBIT(seleFlags[iTrkN2],kBitPionCompat) ){
1290 okForLcTopKpi=kTRUE;
1291 pidLcStatus+=1; // 1= OK as pKpi
1293 if(TESTBIT(seleFlags[iTrkN2],kBitProtonCompat) &&
1294 TESTBIT(seleFlags[iTrkN1],kBitPionCompat) ){
1295 okForLcTopKpi=kTRUE;
1296 pidLcStatus+=2; // 2= OK as piKp
1300 Bool_t okForDsToKKpi=kTRUE;
1301 if(fUseKaonPIDforDs){
1302 if(!TESTBIT(seleFlags[iTrkN1],kBitKaonCompat) &&
1303 !TESTBIT(seleFlags[iTrkN2],kBitKaonCompat) ) okForDsToKKpi=kFALSE;
1306 // back to primary vertex
1307 // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1308 // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1309 // negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1310 SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1311 SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1312 SetParametersAtVertex(negtrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN2));
1313 //printf("********** %d %d %d\n",postrack1->GetID(),negtrack1->GetID(),negtrack2->GetID());
1315 dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1316 if(dcap1n2>dcaMax) { negtrack2=0; continue; }
1317 dcan1n2 = negtrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1318 if(dcan1n2>dcaMax) { negtrack2=0; continue; }
1320 threeTrackArray->AddAt(negtrack1,0);
1321 threeTrackArray->AddAt(postrack1,1);
1322 threeTrackArray->AddAt(negtrack2,2);
1324 // check invariant mass cuts for D+,Ds,Lc
1326 if(fMassCutBeforeVertexing && f3Prong){
1327 negtrack2->GetPxPyPz(momneg2);
1328 Double_t pxDau[3]={momneg1[0],mompos1[0],momneg2[0]};
1329 Double_t pyDau[3]={momneg1[1],mompos1[1],momneg2[1]};
1330 Double_t pzDau[3]={momneg1[2],mompos1[2],momneg2[2]};
1331 // massCutOK = SelectInvMassAndPt3prong(threeTrackArray);
1332 massCutOK = SelectInvMassAndPt3prong(pxDau,pyDau,pzDau,pidLcStatus);
1335 threeTrackArray->Clear();
1341 twoTrackArray2->AddAt(postrack1,0);
1342 twoTrackArray2->AddAt(negtrack2,1);
1344 AliAODVertex *vertexp1n2 = ReconstructSecondaryVertex(twoTrackArray2,dispersion);
1346 twoTrackArray2->Clear();
1352 AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1353 io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,vertexp1n2,dcap1n1,dcap1n2,dcan1n2,okForLcTopKpi,okForDsToKKpi,ok3Prong);
1355 AliAODVertex *v3Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
1356 if(!isLikeSign3Prong) {
1357 rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1358 rd->SetSecondaryVtx(v3Prong);
1359 v3Prong->SetParent(rd);
1360 AddRefs(v3Prong,rd,event,threeTrackArray);
1361 } else { // isLikeSign3Prong
1362 if(fLikeSign3prong){
1363 rd = new(aodLikeSign3ProngRef[iLikeSign3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1364 rd->SetSecondaryVtx(v3Prong);
1365 v3Prong->SetParent(rd);
1366 AddRefs(v3Prong,rd,event,threeTrackArray);
1369 // Set selection bit for PID
1370 SetSelectionBitForPID(fCutsDplustoKpipi,rd,AliRDHFCuts::kDplusPID);
1371 SetSelectionBitForPID(fCutsDstoKKpi,rd,AliRDHFCuts::kDsPID);
1372 SetSelectionBitForPID(fCutsLctopKpi,rd,AliRDHFCuts::kLcPID);
1374 if(io3Prong) {delete io3Prong; io3Prong=NULL;}
1375 if(secVert3PrAOD) {delete secVert3PrAOD; secVert3PrAOD=NULL;}
1377 threeTrackArray->Clear();
1381 } // end 2nd loop on negative tracks
1383 twoTrackArray2->Clear();
1387 } // end 1st loop on negative tracks
1390 } // end 1st loop on positive tracks
1393 AliDebug(1,Form(" Total HF vertices in event = %d;",
1394 (Int_t)aodVerticesHFTClArr->GetEntriesFast()));
1396 AliDebug(1,Form(" D0->Kpi in event = %d;",
1397 (Int_t)aodD0toKpiTClArr->GetEntriesFast()));
1400 AliDebug(1,Form(" JPSI->ee in event = %d;",
1401 (Int_t)aodJPSItoEleTClArr->GetEntriesFast()));
1404 AliDebug(1,Form(" Charm->3Prong in event = %d;",
1405 (Int_t)aodCharm3ProngTClArr->GetEntriesFast()));
1408 AliDebug(1,Form(" Charm->4Prong in event = %d;\n",
1409 (Int_t)aodCharm4ProngTClArr->GetEntriesFast()));
1412 AliDebug(1,Form(" D*->D0pi in event = %d;\n",
1413 (Int_t)aodDstarTClArr->GetEntriesFast()));
1416 AliDebug(1,Form(" cascades -> v0 + track in event = %d;\n",
1417 (Int_t)aodCascadesTClArr->GetEntriesFast()));
1420 AliDebug(1,Form(" Like-sign 2Prong in event = %d;\n",
1421 (Int_t)aodLikeSign2ProngTClArr->GetEntriesFast()));
1423 if(fLikeSign3prong && f3Prong) {
1424 AliDebug(1,Form(" Like-sign 3Prong in event = %d;\n",
1425 (Int_t)aodLikeSign3ProngTClArr->GetEntriesFast()));
1429 twoTrackArray1->Delete(); delete twoTrackArray1;
1430 twoTrackArray2->Delete(); delete twoTrackArray2;
1431 twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
1432 twoTrackArrayV0->Delete(); delete twoTrackArrayV0;
1433 threeTrackArray->Clear();
1434 threeTrackArray->Delete(); delete threeTrackArray;
1435 fourTrackArray->Delete(); delete fourTrackArray;
1436 delete [] seleFlags; seleFlags=NULL;
1437 if(evtNumber) {delete [] evtNumber; evtNumber=NULL;}
1438 tracksAtVertex.Delete();
1441 seleTrksArray.Delete();
1442 if(fAODMap) { delete [] fAODMap; fAODMap=NULL; }
1446 //printf("Trks: total %d sele %d\n",fnTrksTotal,fnSeleTrksTotal);
1450 //----------------------------------------------------------------------------
1451 void AliAnalysisVertexingHF::AddRefs(AliAODVertex *v,AliAODRecoDecayHF *rd,
1452 const AliVEvent *event,
1453 const TObjArray *trkArray) const
1455 // Add the AOD tracks as daughters of the vertex (TRef)
1456 // Also add the references to the primary vertex and to the cuts
1457 //AliCodeTimerAuto("",0);
1460 AddDaughterRefs(v,event,trkArray);
1461 rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1465 rd->SetListOfCutsRef((TList*)fListOfCuts);
1466 //fListOfCuts->Print();
1467 cout<<fListOfCuts<<endl;
1468 TList *l=(TList*)rd->GetListOfCuts();
1470 if(l) {l->Print(); }else{printf("error\n");}
1475 //----------------------------------------------------------------------------
1476 void AliAnalysisVertexingHF::AddDaughterRefs(AliAODVertex *v,
1477 const AliVEvent *event,
1478 const TObjArray *trkArray) const
1480 // Add the AOD tracks as daughters of the vertex (TRef)
1481 //AliCodeTimerAuto("",0);
1483 Int_t nDg = v->GetNDaughters();
1485 if(nDg) dg = v->GetDaughter(0);
1487 if(dg) return; // daughters already added
1489 Int_t nTrks = trkArray->GetEntriesFast();
1491 AliExternalTrackParam *track = 0;
1492 AliAODTrack *aodTrack = 0;
1495 for(Int_t i=0; i<nTrks; i++) {
1496 track = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
1497 id = (Int_t)track->GetID();
1498 //printf("---> %d\n",id);
1499 if(id<0) continue; // this track is a AliAODRecoDecay
1500 aodTrack = (AliAODTrack*)event->GetTrack(fAODMap[id]);
1501 v->AddDaughter(aodTrack);
1506 //---------------------------------------------------------------------------
1507 void AliAnalysisVertexingHF::FixReferences(AliAODEvent *aod)
1509 // Checks that the references to the daughter tracks are properly
1510 // assigned and reassigns them if needed
1512 //AliCodeTimerAuto("",0);
1515 TClonesArray *inputArray=(TClonesArray*)aod->GetList()->FindObject("VerticesHF");
1516 if(!inputArray) return;
1518 AliAODTrack *track = 0;
1519 AliAODVertex *vertex = 0;
1521 Bool_t needtofix=kFALSE;
1522 for(Int_t iv=0; iv<inputArray->GetEntriesFast(); iv++) {
1523 vertex = (AliAODVertex*)inputArray->UncheckedAt(iv);
1524 for(Int_t id=0; id<vertex->GetNDaughters(); id++) {
1525 track = (AliAODTrack*)vertex->GetDaughter(id);
1526 if(!track->GetStatus()) needtofix=kTRUE;
1528 if(needtofix) break;
1531 if(!needtofix) return;
1534 printf("Fixing references\n");
1536 fAODMapSize = 100000;
1537 fAODMap = new Int_t[fAODMapSize];
1538 memset(fAODMap,0,sizeof(Int_t)*fAODMapSize);
1540 for(Int_t i=0; i<aod->GetNumberOfTracks(); i++) {
1541 track = aod->GetTrack(i);
1543 // skip pure ITS SA tracks
1544 if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
1546 // skip tracks without ITS
1547 if(!(track->GetStatus()&AliESDtrack::kITSin)) continue;
1549 // TEMPORARY: check that the cov matrix is there
1550 Double_t covtest[21];
1551 if(!track->GetCovarianceXYZPxPyPz(covtest)) continue;
1554 Int_t ind = (Int_t)track->GetID();
1555 if (ind>-1 && ind < fAODMapSize) fAODMap[ind] = i;
1559 Int_t ids[4]={-1,-1,-1,-1};
1560 for(Int_t iv=0; iv<inputArray->GetEntriesFast(); iv++) {
1561 Bool_t cascade=kFALSE;
1562 vertex = (AliAODVertex*)inputArray->UncheckedAt(iv);
1564 Int_t nDgs = vertex->GetNDaughters();
1565 for(id=0; id<nDgs; id++) {
1566 track = (AliAODTrack*)vertex->GetDaughter(id);
1567 if(track->Charge()==0) {cascade=kTRUE; continue;} // cascade
1568 ids[id]=(Int_t)track->GetID();
1569 vertex->RemoveDaughter(track);
1571 if(cascade) continue;
1572 for(id=0; id<nDgs; id++) {
1573 if (ids[id]>-1 && ids[id] < fAODMapSize) {
1574 track = aod->GetTrack(fAODMap[ids[id]]);
1575 vertex->AddDaughter(track);
1583 //----------------------------------------------------------------------------
1584 AliAODRecoCascadeHF* AliAnalysisVertexingHF::MakeCascade(
1585 TObjArray *twoTrackArray,AliVEvent *event,
1586 AliAODVertex *secVert,
1587 AliAODRecoDecayHF2Prong *rd2Prong,
1591 // Make the cascade as a 2Prong decay and check if it passes Dstar
1592 // reconstruction cuts
1593 //AliCodeTimerAuto("",0);
1597 Bool_t dummy1,dummy2,dummy3;
1599 // We use Make2Prong to construct the AliAODRecoCascadeHF
1600 // (which inherits from AliAODRecoDecayHF2Prong)
1601 AliAODRecoCascadeHF *theCascade =
1602 (AliAODRecoCascadeHF*)Make2Prong(twoTrackArray,event,secVert,dca,
1603 dummy1,dummy2,dummy3);
1604 if(!theCascade) return 0x0;
1607 AliESDtrack *trackPi = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
1608 theCascade->SetCharge(trackPi->Charge());
1610 //--- selection cuts
1612 AliAODRecoCascadeHF *tmpCascade = new AliAODRecoCascadeHF(*theCascade);
1614 Int_t idSoftPi=(Int_t)trackPi->GetID();
1615 if (idSoftPi > -1 && idSoftPi < fAODMapSize) {
1616 AliAODTrack* trackPiAOD=(AliAODTrack*)event->GetTrack(fAODMap[idSoftPi]);
1617 tmpCascade->GetSecondaryVtx()->AddDaughter(trackPiAOD);
1620 tmpCascade->GetSecondaryVtx()->AddDaughter(trackPi);
1622 tmpCascade->GetSecondaryVtx()->AddDaughter(rd2Prong);
1624 AliAODVertex *primVertexAOD=0;
1625 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
1626 // take event primary vertex
1627 primVertexAOD = PrimaryVertex();
1628 tmpCascade->SetOwnPrimaryVtx(primVertexAOD);
1629 rd2Prong->SetOwnPrimaryVtx(primVertexAOD);
1633 okDstar = (Bool_t)fCutsDStartoKpipi->IsSelected(tmpCascade,AliRDHFCuts::kCandidate);
1634 if(okDstar) theCascade->SetSelectionBit(AliRDHFCuts::kDstarCuts);
1636 tmpCascade->GetSecondaryVtx()->RemoveDaughters();
1637 tmpCascade->UnsetOwnPrimaryVtx();
1638 delete tmpCascade; tmpCascade=NULL;
1639 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1640 rd2Prong->UnsetOwnPrimaryVtx();
1642 if(primVertexAOD) {delete primVertexAOD; primVertexAOD=NULL;}
1650 //----------------------------------------------------------------------------
1651 AliAODRecoCascadeHF* AliAnalysisVertexingHF::MakeCascade(
1652 TObjArray *twoTrackArray,AliVEvent *event,
1653 AliAODVertex *secVert,
1659 // Make the cascade as a 2Prong decay and check if it passes
1660 // cascades reconstruction cuts
1661 //AliCodeTimerAuto("",0);
1663 // AliDebug(2,Form(" building the cascade"));
1665 Bool_t dummy1,dummy2,dummy3;
1667 // We use Make2Prong to construct the AliAODRecoCascadeHF
1668 // (which inherits from AliAODRecoDecayHF2Prong)
1669 AliAODRecoCascadeHF *theCascade =
1670 (AliAODRecoCascadeHF*)Make2Prong(twoTrackArray,event,secVert,dca,
1671 dummy1,dummy2,dummy3);
1672 if(!theCascade) return 0x0;
1674 // bachelor track and charge
1675 AliESDtrack *trackBachelor = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
1676 theCascade->SetCharge(trackBachelor->Charge());
1678 //--- selection cuts
1681 AliAODRecoCascadeHF *tmpCascade = new AliAODRecoCascadeHF(*theCascade);
1683 Int_t idBachelor=(Int_t)trackBachelor->GetID();
1684 if (idBachelor > -1 && idBachelor < fAODMapSize) {
1685 AliAODTrack* trackBachelorAOD=(AliAODTrack*)event->GetTrack(fAODMap[idBachelor]);
1686 tmpCascade->GetSecondaryVtx()->AddDaughter(trackBachelorAOD);
1689 tmpCascade->GetSecondaryVtx()->AddDaughter(trackBachelor);
1691 tmpCascade->GetSecondaryVtx()->AddDaughter(v0);
1693 AliAODVertex *primVertexAOD=0;
1694 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
1695 // take event primary vertex
1696 primVertexAOD = PrimaryVertex();
1697 if(!primVertexAOD) primVertexAOD = (AliAODVertex*)event->GetPrimaryVertex();
1698 tmpCascade->SetOwnPrimaryVtx(primVertexAOD);
1702 if(fCascades && fInputAOD){
1703 okCascades = (Bool_t)fCutsLctoV0->IsSelected(tmpCascade,AliRDHFCuts::kCandidate);
1706 //AliDebug(2,Form("The cascade is contructed from ESDs, no cuts are applied"));
1708 }// no cuts implemented from ESDs
1709 tmpCascade->GetSecondaryVtx()->RemoveDaughters();
1710 tmpCascade->UnsetOwnPrimaryVtx();
1711 delete tmpCascade; tmpCascade=NULL;
1712 if(primVertexAOD) {delete primVertexAOD; primVertexAOD=NULL;}
1718 //-----------------------------------------------------------------------------
1719 AliAODRecoDecayHF2Prong *AliAnalysisVertexingHF::Make2Prong(
1720 TObjArray *twoTrackArray,AliVEvent *event,
1721 AliAODVertex *secVert,Double_t dca,
1722 Bool_t &okD0,Bool_t &okJPSI,
1723 Bool_t &okD0fromDstar)
1725 // Make 2Prong candidates and check if they pass D0toKpi or BtoJPSI
1726 // reconstruction cuts
1727 // G.E.Bruno (J/psi), A.Dainese (D0->Kpi)
1728 //AliCodeTimerAuto("",0);
1730 okD0=kFALSE; okJPSI=kFALSE; okD0fromDstar=kFALSE;
1732 Double_t px[2],py[2],pz[2],d0[2],d0err[2];
1733 AliESDtrack *postrack = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
1734 AliESDtrack *negtrack = (AliESDtrack*)twoTrackArray->UncheckedAt(1);
1736 // propagate tracks to secondary vertex, to compute inv. mass
1737 postrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
1738 negtrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
1740 Double_t momentum[3];
1741 postrack->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];
1747 // invariant mass cut (try to improve coding here..)
1748 Bool_t okMassCut=kFALSE;
1749 if(!okMassCut && fD0toKpi) if(SelectInvMassAndPtD0Kpi(px,py,pz)) okMassCut=kTRUE;
1750 if(!okMassCut && fJPSItoEle) if(SelectInvMassAndPtJpsiee(px,py,pz)) okMassCut=kTRUE;
1751 if(!okMassCut && fDstar) if(SelectInvMassAndPtDstarD0pi(px,py,pz)) okMassCut=kTRUE;
1752 if(!okMassCut && fCascades) if(SelectInvMassAndPtCascade(px,py,pz)) okMassCut=kTRUE;
1754 //AliDebug(2," candidate didn't pass mass cut");
1757 // primary vertex to be used by this candidate
1758 AliAODVertex *primVertexAOD = PrimaryVertex(twoTrackArray,event);
1759 if(!primVertexAOD) return 0x0;
1762 Double_t d0z0[2],covd0z0[3];
1763 postrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1765 d0err[0] = TMath::Sqrt(covd0z0[0]);
1766 negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1768 d0err[1] = TMath::Sqrt(covd0z0[0]);
1770 // create the object AliAODRecoDecayHF2Prong
1771 AliAODRecoDecayHF2Prong *the2Prong = new AliAODRecoDecayHF2Prong(secVert,px,py,pz,d0,d0err,dca);
1772 the2Prong->SetOwnPrimaryVtx(primVertexAOD);
1773 UShort_t id[2]={(UShort_t)postrack->GetID(),(UShort_t)negtrack->GetID()};
1774 the2Prong->SetProngIDs(2,id);
1775 delete primVertexAOD; primVertexAOD=NULL;
1778 if(postrack->Charge()!=0 && negtrack->Charge()!=0) { // don't apply these cuts if it's a Dstar
1780 // Add daughter references already here
1781 if(fInputAOD) AddDaughterRefs(secVert,(AliAODEvent*)event,twoTrackArray);
1785 okD0 = (Bool_t)fCutsD0toKpi->IsSelected(the2Prong,AliRDHFCuts::kCandidate,(AliAODEvent*)event);
1786 if(okD0) the2Prong->SetSelectionBit(AliRDHFCuts::kD0toKpiCuts);
1788 //if(fDebug && fD0toKpi) printf(" %d\n",(Int_t)okD0);
1789 // select J/psi from B
1791 okJPSI = (Bool_t)fCutsJpsitoee->IsSelected(the2Prong,AliRDHFCuts::kCandidate);
1793 //if(fDebug && fJPSItoEle) printf(" %d\n",(Int_t)okJPSI);
1794 // select D0->Kpi from Dstar
1796 okD0fromDstar = (Bool_t)fCutsDStartoKpipi->IsD0FromDStarSelected(the2Prong->Pt(),the2Prong,AliRDHFCuts::kCandidate);
1797 if(okD0fromDstar) the2Prong->SetSelectionBit(AliRDHFCuts::kD0fromDstarCuts);
1799 //if(fDebug && fDstar) printf(" %d\n",(Int_t)okD0fromDstar);
1803 // remove the primary vertex (was used only for selection)
1804 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1805 the2Prong->UnsetOwnPrimaryVtx();
1808 // get PID info from ESD
1809 Double_t esdpid0[5]={0.,0.,0.,0.,0.};
1810 if(postrack->GetStatus()&AliESDtrack::kESDpid) postrack->GetESDpid(esdpid0);
1811 Double_t esdpid1[5]={0.,0.,0.,0.,0.};
1812 if(negtrack->GetStatus()&AliESDtrack::kESDpid) negtrack->GetESDpid(esdpid1);
1813 Double_t esdpid[10];
1814 for(Int_t i=0;i<5;i++) {
1815 esdpid[i] = esdpid0[i];
1816 esdpid[5+i] = esdpid1[i];
1818 the2Prong->SetPID(2,esdpid);
1822 //----------------------------------------------------------------------------
1823 AliAODRecoDecayHF3Prong* AliAnalysisVertexingHF::Make3Prong(
1824 TObjArray *threeTrackArray,AliVEvent *event,
1825 AliAODVertex *secVert,Double_t dispersion,
1826 const AliAODVertex *vertexp1n1,const AliAODVertex *vertexp2n1,
1827 Double_t dcap1n1,Double_t dcap2n1,Double_t dcap1p2,
1828 Bool_t useForLc, Bool_t useForDs, Bool_t &ok3Prong)
1830 // Make 3Prong candidates and check if they pass Dplus or Ds or Lambdac
1831 // reconstruction cuts
1834 //AliCodeTimerAuto("",0);
1837 if(!secVert || !vertexp1n1 || !vertexp2n1) return 0x0;
1839 Double_t px[3],py[3],pz[3],d0[3],d0err[3];
1840 Double_t momentum[3];
1843 AliESDtrack *postrack1 = (AliESDtrack*)threeTrackArray->UncheckedAt(0);
1844 AliESDtrack *negtrack = (AliESDtrack*)threeTrackArray->UncheckedAt(1);
1845 AliESDtrack *postrack2 = (AliESDtrack*)threeTrackArray->UncheckedAt(2);
1847 postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
1848 negtrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
1849 postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
1850 postrack1->GetPxPyPz(momentum);
1851 px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
1852 negtrack->GetPxPyPz(momentum);
1853 px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
1854 postrack2->GetPxPyPz(momentum);
1855 px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2];
1857 // invariant mass cut for D+, Ds, Lc
1858 Bool_t okMassCut=kFALSE;
1859 if(fMassCutBeforeVertexing) okMassCut=kTRUE; // mass cut already done and passed
1860 if(!okMassCut && f3Prong) if(SelectInvMassAndPt3prong(px,py,pz)) okMassCut=kTRUE;
1862 //AliDebug(2," candidate didn't pass mass cut");
1866 // primary vertex to be used by this candidate
1867 AliAODVertex *primVertexAOD = PrimaryVertex(threeTrackArray,event);
1868 if(!primVertexAOD) return 0x0;
1870 Double_t d0z0[2],covd0z0[3];
1871 postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1873 d0err[0] = TMath::Sqrt(covd0z0[0]);
1874 negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1876 d0err[1] = TMath::Sqrt(covd0z0[0]);
1877 postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1879 d0err[2] = TMath::Sqrt(covd0z0[0]);
1882 // create the object AliAODRecoDecayHF3Prong
1883 Double_t pos[3]; primVertexAOD->GetXYZ(pos);
1884 Double_t dca[3]={dcap1n1,dcap2n1,dcap1p2};
1885 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]));
1886 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]));
1887 Short_t charge=(Short_t)(postrack1->Charge()+postrack2->Charge()+negtrack->Charge());
1888 AliAODRecoDecayHF3Prong *the3Prong = new AliAODRecoDecayHF3Prong(secVert,px,py,pz,d0,d0err,dca,dispersion,dist12,dist23,charge);
1889 the3Prong->SetOwnPrimaryVtx(primVertexAOD);
1890 UShort_t id[3]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack->GetID(),(UShort_t)postrack2->GetID()};
1891 the3Prong->SetProngIDs(3,id);
1893 delete primVertexAOD; primVertexAOD=NULL;
1895 // Add daughter references already here
1896 if(fInputAOD) AddDaughterRefs(secVert,(AliAODEvent*)event,threeTrackArray);
1898 // select D+->Kpipi, Ds->KKpi, Lc->pKpi
1902 if(fOKInvMassDplus && fCutsDplustoKpipi->IsSelected(the3Prong,AliRDHFCuts::kCandidate,(AliAODEvent*)event)) {
1904 the3Prong->SetSelectionBit(AliRDHFCuts::kDplusCuts);
1906 if(useForDs && fOKInvMassDs){
1907 if(fCutsDstoKKpi->IsSelected(the3Prong,AliRDHFCuts::kCandidate,(AliAODEvent*)event)) {
1909 the3Prong->SetSelectionBit(AliRDHFCuts::kDsCuts);
1912 if(useForLc && fOKInvMassLc){
1913 if(fCutsLctopKpi->IsSelected(the3Prong,AliRDHFCuts::kCandidate,(AliAODEvent*)event)) {
1915 the3Prong->SetSelectionBit(AliRDHFCuts::kLcCuts);
1919 //if(fDebug) printf("ok3Prong: %d\n",(Int_t)ok3Prong);
1921 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
1922 the3Prong->UnsetOwnPrimaryVtx();
1925 // get PID info from ESD
1926 Double_t esdpid0[5]={0.,0.,0.,0.,0.};
1927 if(postrack1->GetStatus()&AliESDtrack::kESDpid) postrack1->GetESDpid(esdpid0);
1928 Double_t esdpid1[5]={0.,0.,0.,0.,0.};
1929 if(negtrack->GetStatus()&AliESDtrack::kESDpid) negtrack->GetESDpid(esdpid1);
1930 Double_t esdpid2[5]={0.,0.,0.,0.,0.};
1931 if(postrack2->GetStatus()&AliESDtrack::kESDpid) postrack2->GetESDpid(esdpid2);
1933 Double_t esdpid[15];
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];
1939 the3Prong->SetPID(3,esdpid);
1943 //----------------------------------------------------------------------------
1944 AliAODRecoDecayHF4Prong* AliAnalysisVertexingHF::Make4Prong(
1945 TObjArray *fourTrackArray,AliVEvent *event,
1946 AliAODVertex *secVert,
1947 const AliAODVertex *vertexp1n1,
1948 const AliAODVertex *vertexp1n1p2,
1949 Double_t dcap1n1,Double_t dcap1n2,
1950 Double_t dcap2n1,Double_t dcap2n2,
1953 // Make 4Prong candidates and check if they pass D0toKpipipi
1954 // reconstruction cuts
1955 // G.E.Bruno, R.Romita
1956 //AliCodeTimerAuto("",0);
1959 if(!secVert || !vertexp1n1 || !vertexp1n1p2) return 0x0;
1961 Double_t px[4],py[4],pz[4],d0[4],d0err[4];//d0z[3];
1963 AliESDtrack *postrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(0);
1964 AliESDtrack *negtrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(1);
1965 AliESDtrack *postrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(2);
1966 AliESDtrack *negtrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(3);
1968 postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
1969 negtrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
1970 postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
1971 negtrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
1973 Double_t momentum[3];
1974 postrack1->GetPxPyPz(momentum);
1975 px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
1976 negtrack1->GetPxPyPz(momentum);
1977 px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
1978 postrack2->GetPxPyPz(momentum);
1979 px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2];
1980 negtrack2->GetPxPyPz(momentum);
1981 px[3] = momentum[0]; py[3] = momentum[1]; pz[3] = momentum[2];
1983 // invariant mass cut for rho or D0 (try to improve coding here..)
1984 Bool_t okMassCut=kFALSE;
1985 if(fMassCutBeforeVertexing) okMassCut=kTRUE; // mass cut already done and passed
1986 if(!okMassCut && !(fCutsD0toKpipipi->GetUsePID())) { //no PID, to be implemented with PID
1987 if(SelectInvMassAndPt4prong(px,py,pz)) okMassCut=kTRUE;
1990 //if(fDebug) printf(" candidate didn't pass mass cut\n");
1991 //printf(" candidate didn't pass mass cut\n");
1995 // primary vertex to be used by this candidate
1996 AliAODVertex *primVertexAOD = PrimaryVertex(fourTrackArray,event);
1997 if(!primVertexAOD) return 0x0;
1999 Double_t d0z0[2],covd0z0[3];
2000 postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2002 d0err[0] = TMath::Sqrt(covd0z0[0]);
2003 negtrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2005 d0err[1] = TMath::Sqrt(covd0z0[0]);
2006 postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2008 d0err[2] = TMath::Sqrt(covd0z0[0]);
2009 negtrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2011 d0err[3] = TMath::Sqrt(covd0z0[0]);
2014 // create the object AliAODRecoDecayHF4Prong
2015 Double_t pos[3]; primVertexAOD->GetXYZ(pos);
2016 Double_t dca[6]={dcap1n1,0.,dcap1n2,dcap2n1,0.,dcap2n2};
2017 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]));
2018 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]));
2019 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]));
2021 AliAODRecoDecayHF4Prong *the4Prong = new AliAODRecoDecayHF4Prong(secVert,px,py,pz,d0,d0err,dca,dist12,dist3,dist4,charge);
2022 the4Prong->SetOwnPrimaryVtx(primVertexAOD);
2023 UShort_t id[4]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack1->GetID(),(UShort_t)postrack2->GetID(),(UShort_t)negtrack2->GetID()};
2024 the4Prong->SetProngIDs(4,id);
2026 delete primVertexAOD; primVertexAOD=NULL;
2028 ok4Prong=(Bool_t)fCutsD0toKpipipi->IsSelected(the4Prong,AliRDHFCuts::kCandidate);
2031 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent) {
2032 the4Prong->UnsetOwnPrimaryVtx();
2036 // get PID info from ESD
2037 Double_t esdpid0[5]={0.,0.,0.,0.,0.};
2038 if(postrack1->GetStatus()&AliESDtrack::kESDpid) postrack1->GetESDpid(esdpid0);
2039 Double_t esdpid1[5]={0.,0.,0.,0.,0.};
2040 if(negtrack1->GetStatus()&AliESDtrack::kESDpid) negtrack1->GetESDpid(esdpid1);
2041 Double_t esdpid2[5]={0.,0.,0.,0.,0.};
2042 if(postrack2->GetStatus()&AliESDtrack::kESDpid) postrack2->GetESDpid(esdpid2);
2043 Double_t esdpid3[5]={0.,0.,0.,0.,0.};
2044 if(negtrack2->GetStatus()&AliESDtrack::kESDpid) negtrack2->GetESDpid(esdpid3);
2046 Double_t esdpid[20];
2047 for(Int_t i=0;i<5;i++) {
2048 esdpid[i] = esdpid0[i];
2049 esdpid[5+i] = esdpid1[i];
2050 esdpid[10+i] = esdpid2[i];
2051 esdpid[15+i] = esdpid3[i];
2053 the4Prong->SetPID(4,esdpid);
2057 //-----------------------------------------------------------------------------
2058 AliAODVertex* AliAnalysisVertexingHF::PrimaryVertex(const TObjArray *trkArray,
2059 AliVEvent *event) const
2061 // Returns primary vertex to be used for this candidate
2062 //AliCodeTimerAuto("",0);
2064 AliESDVertex *vertexESD = 0;
2065 AliAODVertex *vertexAOD = 0;
2068 if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
2069 // primary vertex from the input event
2071 vertexESD = new AliESDVertex(*fV1);
2074 // primary vertex specific to this candidate
2076 Int_t nTrks = trkArray->GetEntriesFast();
2077 AliVertexerTracks *vertexer = new AliVertexerTracks(event->GetMagneticField());
2079 if(fRecoPrimVtxSkippingTrks) {
2080 // recalculating the vertex
2082 if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraint")) {
2083 Float_t diamondcovxy[3];
2084 event->GetDiamondCovXY(diamondcovxy);
2085 Double_t pos[3]={event->GetDiamondX(),event->GetDiamondY(),0.};
2086 Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.*10.};
2087 AliESDVertex *diamond = new AliESDVertex(pos,cov,1.,1);
2088 vertexer->SetVtxStart(diamond);
2089 delete diamond; diamond=NULL;
2090 if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraintOnlyFitter"))
2091 vertexer->SetOnlyFitter();
2093 Int_t skipped[1000];
2094 Int_t nTrksToSkip=0,id;
2095 AliExternalTrackParam *t = 0;
2096 for(Int_t i=0; i<nTrks; i++) {
2097 t = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
2098 id = (Int_t)t->GetID();
2100 skipped[nTrksToSkip++] = id;
2103 // For AOD, skip also tracks without covariance matrix
2105 Double_t covtest[21];
2106 for(Int_t j=0; j<event->GetNumberOfTracks(); j++) {
2107 AliVTrack *vtrack = (AliVTrack*)event->GetTrack(j);
2108 if(!vtrack->GetCovarianceXYZPxPyPz(covtest)) {
2109 id = (Int_t)vtrack->GetID();
2111 skipped[nTrksToSkip++] = id;
2115 for(Int_t ijk=nTrksToSkip; ijk<1000; ijk++) skipped[ijk]=-1;
2117 vertexer->SetSkipTracks(nTrksToSkip,skipped);
2118 vertexESD = (AliESDVertex*)vertexer->FindPrimaryVertex(event);
2120 } else if(fRmTrksFromPrimVtx && nTrks>0) {
2121 // removing the prongs tracks
2123 TObjArray rmArray(nTrks);
2124 UShort_t *rmId = new UShort_t[nTrks];
2125 AliESDtrack *esdTrack = 0;
2127 for(Int_t i=0; i<nTrks; i++) {
2128 t = (AliESDtrack*)trkArray->UncheckedAt(i);
2129 esdTrack = new AliESDtrack(*t);
2130 rmArray.AddLast(esdTrack);
2131 if(esdTrack->GetID()>=0) {
2132 rmId[i]=(UShort_t)esdTrack->GetID();
2137 Float_t diamondxy[2]={event->GetDiamondX(),event->GetDiamondY()};
2138 vertexESD = vertexer->RemoveTracksFromVertex(fV1,&rmArray,rmId,diamondxy);
2139 delete [] rmId; rmId=NULL;
2144 if(!vertexESD) return vertexAOD;
2145 if(vertexESD->GetNContributors()<=0) {
2146 //AliDebug(2,"vertexing failed");
2147 delete vertexESD; vertexESD=NULL;
2151 delete vertexer; vertexer=NULL;
2155 // convert to AliAODVertex
2156 Double_t pos[3],cov[6],chi2perNDF;
2157 vertexESD->GetXYZ(pos); // position
2158 vertexESD->GetCovMatrix(cov); //covariance matrix
2159 chi2perNDF = vertexESD->GetChi2toNDF();
2160 delete vertexESD; vertexESD=NULL;
2162 vertexAOD = new AliAODVertex(pos,cov,chi2perNDF);
2166 //-----------------------------------------------------------------------------
2167 void AliAnalysisVertexingHF::PrintStatus() const {
2168 // Print parameters being used
2170 //printf("Preselections:\n");
2171 // fTrackFilter->Dump();
2173 printf("Secondary vertex with Kalman filter package (AliKFParticle)\n");
2175 printf("Secondary vertex with AliVertexerTracks\n");
2177 if(fRecoPrimVtxSkippingTrks) printf("RecoPrimVtxSkippingTrks\n");
2178 if(fRmTrksFromPrimVtx) printf("RmTrksFromPrimVtx\n");
2180 printf("Reconstruct D0->Kpi candidates with cuts:\n");
2181 if(fCutsD0toKpi) fCutsD0toKpi->PrintAll();
2184 printf("Reconstruct D*->D0pi candidates with cuts:\n");
2185 if(fFindVertexForDstar) {
2186 printf(" Reconstruct a secondary vertex for the D*\n");
2188 printf(" Assume the D* comes from the primary vertex\n");
2190 if(fCutsDStartoKpipi) fCutsDStartoKpipi->PrintAll();
2193 printf("Reconstruct J/psi from B candidates with cuts:\n");
2194 if(fCutsJpsitoee) fCutsJpsitoee->PrintAll();
2197 printf("Reconstruct 3 prong candidates.\n");
2198 printf(" D+->Kpipi cuts:\n");
2199 if(fCutsDplustoKpipi) fCutsDplustoKpipi->PrintAll();
2200 printf(" Ds->KKpi cuts:\n");
2201 if(fCutsDstoKKpi) fCutsDstoKKpi->PrintAll();
2202 printf(" Lc->pKpi cuts:\n");
2203 if(fCutsLctopKpi) fCutsLctopKpi->PrintAll();
2206 printf("Reconstruct 4 prong candidates.\n");
2207 printf(" D0->Kpipipi cuts:\n");
2208 if(fCutsD0toKpipipi) fCutsD0toKpipipi->PrintAll();
2211 printf("Reconstruct cascades candidates formed with v0s.\n");
2212 printf(" Lc -> k0s P & Lc -> L Pi cuts:\n");
2213 if(fCutsLctoV0) fCutsLctoV0->PrintAll();
2218 //-----------------------------------------------------------------------------
2219 AliAODVertex* AliAnalysisVertexingHF::ReconstructSecondaryVertex(TObjArray *trkArray,
2220 Double_t &dispersion,Bool_t useTRefArray) const
2222 // Secondary vertex reconstruction with AliVertexerTracks or AliKFParticle
2223 //AliCodeTimerAuto("",0);
2225 AliESDVertex *vertexESD = 0;
2226 AliAODVertex *vertexAOD = 0;
2228 if(!fSecVtxWithKF) { // AliVertexerTracks
2230 fVertexerTracks->SetVtxStart(fV1);
2231 vertexESD = (AliESDVertex*)fVertexerTracks->VertexForSelectedESDTracks(trkArray);
2233 if(!vertexESD) return vertexAOD;
2235 if(vertexESD->GetNContributors()!=trkArray->GetEntriesFast()) {
2236 //AliDebug(2,"vertexing failed");
2237 delete vertexESD; vertexESD=NULL;
2241 Double_t vertRadius2=vertexESD->GetXv()*vertexESD->GetXv()+vertexESD->GetYv()*vertexESD->GetYv();
2243 // vertex outside beam pipe, reject candidate to avoid propagation through material
2244 delete vertexESD; vertexESD=NULL;
2248 } else { // Kalman Filter vertexer (AliKFParticle)
2250 AliKFParticle::SetField(fBzkG);
2252 AliKFVertex vertexKF;
2254 Int_t nTrks = trkArray->GetEntriesFast();
2255 for(Int_t i=0; i<nTrks; i++) {
2256 AliESDtrack *esdTrack = (AliESDtrack*)trkArray->At(i);
2257 AliKFParticle daughterKF(*esdTrack,211);
2258 vertexKF.AddDaughter(daughterKF);
2260 vertexESD = new AliESDVertex(vertexKF.Parameters(),
2261 vertexKF.CovarianceMatrix(),
2263 vertexKF.GetNContributors());
2267 // convert to AliAODVertex
2268 Double_t pos[3],cov[6],chi2perNDF;
2269 vertexESD->GetXYZ(pos); // position
2270 vertexESD->GetCovMatrix(cov); //covariance matrix
2271 chi2perNDF = vertexESD->GetChi2toNDF();
2272 dispersion = vertexESD->GetDispersion();
2273 delete vertexESD; vertexESD=NULL;
2275 Int_t nprongs= (useTRefArray ? 0 : trkArray->GetEntriesFast());
2276 vertexAOD = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,nprongs);
2280 //-----------------------------------------------------------------------------
2281 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPt3prong(TObjArray *trkArray){
2282 // Invariant mass cut on tracks
2283 //AliCodeTimerAuto("",0);
2285 Int_t retval=kFALSE;
2286 Double_t momentum[3];
2287 Double_t px[3],py[3],pz[3];
2288 for(Int_t iTrack=0; iTrack<3; iTrack++){
2289 AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
2290 track->GetPxPyPz(momentum);
2291 px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
2293 retval = SelectInvMassAndPt3prong(px,py,pz);
2298 //-----------------------------------------------------------------------------
2299 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPt4prong(TObjArray *trkArray){
2300 // Invariant mass cut on tracks
2301 //AliCodeTimerAuto("",0);
2303 Int_t retval=kFALSE;
2304 Double_t momentum[3];
2305 Double_t px[4],py[4],pz[4];
2307 for(Int_t iTrack=0; iTrack<4; iTrack++){
2308 AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
2309 track->GetPxPyPz(momentum);
2310 px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
2313 retval = SelectInvMassAndPt4prong(px,py,pz);
2317 //-----------------------------------------------------------------------------
2318 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtDstarD0pi(TObjArray *trkArray){
2319 // Invariant mass cut on tracks
2320 //AliCodeTimerAuto("",0);
2322 Int_t retval=kFALSE;
2323 Double_t momentum[3];
2324 Double_t px[2],py[2],pz[2];
2326 for(Int_t iTrack=0; iTrack<2; iTrack++){
2327 AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
2328 track->GetPxPyPz(momentum);
2329 px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
2331 retval = SelectInvMassAndPtDstarD0pi(px,py,pz);
2335 //-----------------------------------------------------------------------------
2336 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtD0Kpi(Double_t *px,
2339 // Check invariant mass cut and pt candidate cut
2340 //AliCodeTimerAuto("",0);
2344 Double_t minv2,mrange;
2345 Double_t lolim,hilim;
2347 Bool_t retval=kFALSE;
2349 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
2350 fOKInvMassD0=kFALSE;
2352 minPt=fCutsD0toKpi->GetMinPtCandidate();
2354 if(fMassCalc2->Pt2() < minPt*minPt) return retval;
2356 mrange=fCutsD0toKpi->GetMassCut();
2357 lolim=fMassDzero-mrange;
2358 hilim=fMassDzero+mrange;
2359 pdg2[0]=211; pdg2[1]=321;
2360 minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
2361 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2365 pdg2[0]=321; pdg2[1]=211;
2366 minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
2367 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2374 //-----------------------------------------------------------------------------
2375 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtJpsiee(Double_t *px,
2378 // Check invariant mass cut and pt candidate cut
2379 //AliCodeTimerAuto("",0);
2383 Double_t minv2,mrange;
2384 Double_t lolim,hilim;
2386 Bool_t retval=kFALSE;
2388 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
2389 fOKInvMassJpsi=kFALSE;
2391 minPt=fCutsJpsitoee->GetMinPtCandidate();
2393 if(fMassCalc2->Pt2() < minPt*minPt) return retval;
2395 mrange=fCutsJpsitoee->GetMassCut();
2396 lolim=fMassJpsi-mrange;
2397 hilim=fMassJpsi+mrange;
2399 pdg2[0]=11; pdg2[1]=11;
2400 minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
2401 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2403 fOKInvMassJpsi=kTRUE;
2408 //-----------------------------------------------------------------------------
2409 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPt3prong(Double_t *px,
2413 // Check invariant mass cut and pt candidate cut
2414 //AliCodeTimerAuto("",0);
2418 Double_t minv2,mrange;
2419 Double_t lolim,hilim;
2421 Bool_t retval=kFALSE;
2424 fMassCalc3->SetPxPyPzProngs(nprongs,px,py,pz);
2425 fOKInvMassDplus=kFALSE;
2426 fOKInvMassDs=kFALSE;
2427 fOKInvMassLc=kFALSE;
2429 minPt=TMath::Min(fCutsDplustoKpipi->GetMinPtCandidate(),fCutsDstoKKpi->GetMinPtCandidate());
2430 minPt=TMath::Min(minPt,fCutsLctopKpi->GetMinPtCandidate());
2432 if(fMassCalc3->Pt2() < minPt*minPt) return retval;
2434 mrange=fCutsDplustoKpipi->GetMassCut();
2435 lolim=fMassDplus-mrange;
2436 hilim=fMassDplus+mrange;
2437 pdg3[0]=211; pdg3[1]=321; pdg3[2]=211;
2438 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2439 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2441 fOKInvMassDplus=kTRUE;
2444 mrange=fCutsDstoKKpi->GetMassCut();
2445 lolim=fMassDs-mrange;
2446 hilim=fMassDs+mrange;
2447 pdg3[0]=321; pdg3[1]=321; pdg3[2]=211;
2448 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2449 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2453 pdg3[0]=211; pdg3[1]=321; pdg3[2]=321;
2454 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2455 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2460 mrange=fCutsLctopKpi->GetMassCut();
2461 lolim=fMassLambdaC-mrange;
2462 hilim=fMassLambdaC+mrange;
2464 pdg3[0]=2212; pdg3[1]=321; pdg3[2]=211;
2465 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2466 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2472 pdg3[0]=211; pdg3[1]=321; pdg3[2]=2212;
2473 minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
2474 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2483 //-----------------------------------------------------------------------------
2484 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtDstarD0pi(Double_t *px,
2487 // Check invariant mass cut and pt candidate cut
2488 //AliCodeTimerAuto("",0);
2492 Double_t minv2,mrange;
2493 Double_t lolim,hilim;
2495 Bool_t retval=kFALSE;
2497 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
2498 fOKInvMassDstar=kFALSE;
2500 minPt=fCutsDStartoKpipi->GetMinPtCandidate();
2502 if(fMassCalc2->Pt2() < minPt*minPt) return retval;
2504 pdg2[0]=211; pdg2[1]=421; // in twoTrackArrayCasc we put the pion first
2505 mrange=fCutsDStartoKpipi->GetMassCut();
2506 lolim=fMassDstar-mrange;
2507 hilim=fMassDstar+mrange;
2508 minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
2509 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2511 fOKInvMassDstar=kTRUE;
2517 //-----------------------------------------------------------------------------
2518 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPt4prong(Double_t *px,
2521 // Check invariant mass cut and pt candidate cut
2522 //AliCodeTimerAuto("",0);
2526 Double_t minv2,mrange;
2527 Double_t lolim,hilim;
2529 Bool_t retval=kFALSE;
2531 // D0->Kpipipi without PID
2532 fMassCalc4->SetPxPyPzProngs(nprongs,px,py,pz);
2533 fOKInvMassD0to4p=kFALSE;
2535 minPt=fCutsD0toKpipipi->GetMinPtCandidate();
2537 if(fMassCalc4->Pt2() < minPt*minPt) return retval;
2539 mrange=fCutsD0toKpipipi->GetMassCut();
2540 lolim=fMassDzero-mrange;
2541 hilim=fMassDzero+mrange;
2543 pdg4[0]=321; pdg4[1]=211; pdg4[2]=211; pdg4[3]=211;
2544 minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
2545 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2547 fOKInvMassD0to4p=kTRUE;
2550 pdg4[0]=211; pdg4[1]=321; pdg4[2]=211; pdg4[3]=211;
2551 minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
2552 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2554 fOKInvMassD0to4p=kTRUE;
2557 pdg4[0]=211; pdg4[1]=211; pdg4[2]=321; pdg4[3]=211;
2558 minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
2559 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2561 fOKInvMassD0to4p=kTRUE;
2564 pdg4[0]=211; pdg4[1]=211; pdg4[2]=211; pdg4[3]=321;
2565 minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
2566 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2568 fOKInvMassD0to4p=kTRUE;
2573 //-----------------------------------------------------------------------------
2574 Bool_t AliAnalysisVertexingHF::SelectInvMassAndPtCascade(Double_t *px,
2577 // Check invariant mass cut and pt candidate cut
2578 //AliCodeTimerAuto("",0);
2582 Double_t minv2,mrange;
2583 Double_t lolim,hilim;
2585 Bool_t retval=kFALSE;
2587 fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
2588 minPt=fCutsLctoV0->GetMinPtCandidate();
2589 fOKInvMassLctoV0=kFALSE;
2590 mrange=fCutsLctoV0->GetMassCut();
2591 lolim=fMassLambdaC-mrange;
2592 hilim=fMassLambdaC+mrange;
2593 pdg2[0]=2212;pdg2[1]=310;
2594 minv2=fMassCalc2->InvMass2(2,pdg2);
2595 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2597 fOKInvMassLctoV0=kTRUE;
2599 pdg2[0]=211;pdg2[1]=3122;
2600 minv2=fMassCalc2->InvMass2(2,pdg2);
2601 if(minv2>lolim*lolim && minv2<hilim*hilim ){
2603 fOKInvMassLctoV0=kTRUE;
2608 //-----------------------------------------------------------------------------
2609 void AliAnalysisVertexingHF::SelectTracksAndCopyVertex(const AliVEvent *event,
2611 TObjArray &seleTrksArray,
2612 TObjArray &tracksAtVertex,
2614 UChar_t *seleFlags,Int_t *evtNumber)
2616 // Apply single-track preselection.
2617 // Fill a TObjArray with selected tracks (for displaced vertices or
2618 // soft pion from D*). Selection flag stored in seleFlags.
2619 // Create the AliESDVertex object (convert from AliAODVertex if necessary)
2620 // In case of AOD input, also fill fAODMap for track index<->ID
2621 //AliCodeTimerAuto("",0);
2623 const AliVVertex *vprimary = event->GetPrimaryVertex();
2625 if(fV1) { delete fV1; fV1=NULL; }
2626 if(fAODMap) { delete [] fAODMap; fAODMap=NULL; }
2629 UShort_t *indices = 0;
2630 Double_t pos[3],cov[6];
2631 const Int_t entries = event->GetNumberOfTracks();
2632 AliCentrality* cent;
2634 if(!fInputAOD) { // ESD
2635 fV1 = new AliESDVertex(*((AliESDVertex*)vprimary));
2636 cent=((AliESDEvent*)event)->GetCentrality();
2638 vprimary->GetXYZ(pos);
2639 vprimary->GetCovarianceMatrix(cov);
2640 fV1 = new AliESDVertex(pos,cov,100.,100,vprimary->GetName());
2641 if(entries<=0) return;
2642 indices = new UShort_t[entries];
2643 memset(indices,0,sizeof(UShort_t)*entries);
2644 fAODMapSize = 100000;
2645 fAODMap = new Int_t[fAODMapSize];
2646 memset(fAODMap,0,sizeof(Int_t)*fAODMapSize);
2647 cent=((AliAODEvent*)event)->GetCentrality();
2649 Float_t centperc=cent->GetCentralityPercentile("V0M");
2651 Bool_t okDisplaced=kFALSE,okSoftPi=kFALSE,okFor3Prong=kFALSE;
2654 // transfer ITS tracks from event to arrays
2655 for(Int_t i=0; i<entries; i++) {
2657 track = (AliVTrack*)event->GetTrack(i);
2659 // skip pure ITS SA tracks
2660 if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
2662 // skip tracks without ITS
2663 if(!(track->GetStatus()&AliESDtrack::kITSin)) continue;
2665 // skip tracks with negative ID
2666 // (these are duplicated TPC-only AOD tracks, for jet analysis...)
2667 if(track->GetID()<0) continue;
2669 // TEMPORARY: check that the cov matrix is there
2670 Double_t covtest[21];
2671 if(!track->GetCovarianceXYZPxPyPz(covtest)) continue;
2675 AliAODTrack *aodt = (AliAODTrack*)track;
2676 if(aodt->GetUsedForPrimVtxFit()) {
2677 indices[nindices]=aodt->GetID(); nindices++;
2679 Int_t ind = (Int_t)aodt->GetID();
2680 if (ind>-1 && ind < fAODMapSize) fAODMap[ind] = i;
2683 AliESDtrack *esdt = 0;
2686 esdt = (AliESDtrack*)track;
2688 esdt = new AliESDtrack(track);
2691 // single track selection
2692 okDisplaced=kFALSE; okSoftPi=kFALSE; okFor3Prong=kFALSE;
2693 if(fMixEvent && i<trkEntries){
2694 evtNumber[i]=((AliMixedEvent*)event)->EventIndex(i);
2695 const AliVVertex* eventVtx=((AliMixedEvent*)event)->GetEventVertex(i);
2696 Double_t vtxPos[3],primPos[3],primCov[6],trasl[3];
2697 eventVtx->GetXYZ(vtxPos);
2698 vprimary->GetXYZ(primPos);
2699 eventVtx->GetCovarianceMatrix(primCov);
2700 for(Int_t ind=0;ind<3;ind++){
2701 trasl[ind]=vtxPos[ind]-primPos[ind];
2704 Bool_t isTransl=esdt->Translate(trasl,primCov);
2712 if(SingleTrkCuts(esdt,centperc,okDisplaced,okSoftPi,okFor3Prong) && nSeleTrks<trkEntries) {
2713 esdt->PropagateToDCA(fV1,fBzkG,kVeryBig);
2714 seleTrksArray.AddLast(esdt);
2715 tracksAtVertex.AddLast(new AliExternalTrackParam(*esdt));
2716 seleFlags[nSeleTrks]=0;
2717 if(okDisplaced) SETBIT(seleFlags[nSeleTrks],kBitDispl);
2718 if(okFor3Prong) SETBIT(seleFlags[nSeleTrks],kBit3Prong);
2719 if(okSoftPi) SETBIT(seleFlags[nSeleTrks],kBitSoftPi);
2722 SETBIT(seleFlags[nSeleTrks],kBitPionCompat);
2723 SETBIT(seleFlags[nSeleTrks],kBitKaonCompat);
2724 SETBIT(seleFlags[nSeleTrks],kBitProtonCompat);
2725 Bool_t useTPC=kTRUE;
2727 Double_t nsigmatofPi= fPidResponse->NumberOfSigmasTOF(esdt,AliPID::kPion);
2728 if(nsigmatofPi>-990. && (nsigmatofPi<-fnSigmaTOFPionLow || nsigmatofPi>fnSigmaTOFPionHi)){
2729 CLRBIT(seleFlags[nSeleTrks],kBitPionCompat);
2731 Double_t nsigmatofK= fPidResponse->NumberOfSigmasTOF(esdt,AliPID::kKaon);
2732 if(nsigmatofK>-990. && (nsigmatofK<-fnSigmaTOFKaonLow || nsigmatofK>fnSigmaTOFKaonHi)){
2733 CLRBIT(seleFlags[nSeleTrks],kBitKaonCompat);
2735 Double_t nsigmatofP= fPidResponse->NumberOfSigmasTOF(esdt,AliPID::kProton);
2736 if(nsigmatofP>-990. && (nsigmatofP<-fnSigmaTOFProtonLow || nsigmatofP>fnSigmaTOFProtonHi)){
2737 CLRBIT(seleFlags[nSeleTrks],kBitProtonCompat);
2739 if(fUseTPCPIDOnlyIfNoTOF && nsigmatofPi>-990.) useTPC=kFALSE;
2741 if(useTPC && fUseTPCPID && esdt->P()<fMaxMomForTPCPid){
2742 Double_t nsigmatpcPi= fPidResponse->NumberOfSigmasTPC(esdt,AliPID::kPion);
2743 if(nsigmatpcPi>-990. && (nsigmatpcPi<-fnSigmaTPCPionLow || nsigmatpcPi>fnSigmaTPCPionHi)){
2744 CLRBIT(seleFlags[nSeleTrks],kBitPionCompat);
2746 Double_t nsigmatpcK= fPidResponse->NumberOfSigmasTPC(esdt,AliPID::kKaon);
2747 if(nsigmatpcK>-990. && (nsigmatpcK<-fnSigmaTPCKaonLow || nsigmatpcK>fnSigmaTPCKaonHi)){
2748 CLRBIT(seleFlags[nSeleTrks],kBitKaonCompat);
2750 Double_t nsigmatpcP= fPidResponse->NumberOfSigmasTPC(esdt,AliPID::kProton);
2751 if(nsigmatpcP>-990. && (nsigmatpcP<-fnSigmaTPCProtonLow || nsigmatpcP>fnSigmaTPCProtonHi)){
2752 CLRBIT(seleFlags[nSeleTrks],kBitProtonCompat);
2757 if(fInputAOD) delete esdt;
2762 } // end loop on tracks
2764 // primary vertex from AOD
2766 delete fV1; fV1=NULL;
2767 vprimary->GetXYZ(pos);
2768 vprimary->GetCovarianceMatrix(cov);
2769 Double_t chi2toNDF = vprimary->GetChi2perNDF();
2770 Int_t ncontr=nindices;
2771 if(!strcmp(vprimary->GetTitle(),"VertexerTracksWithContraint")) ncontr += 1;
2772 Double_t chi2=chi2toNDF*(2.*(Double_t)ncontr-3.);
2773 fV1 = new AliESDVertex(pos,cov,chi2,ncontr,vprimary->GetName());
2774 fV1->SetTitle(vprimary->GetTitle());
2775 fV1->SetIndices(nindices,indices);
2777 if(indices) { delete [] indices; indices=NULL; }
2782 //-----------------------------------------------------------------------------
2783 void AliAnalysisVertexingHF::SetSelectionBitForPID(AliRDHFCuts *cuts,AliAODRecoDecayHF *rd,Int_t bit) {
2785 // Set the selection bit for PID
2787 //AliCodeTimerAuto("",0);
2788 if(cuts->GetPidHF()) {
2789 Bool_t usepid=cuts->GetIsUsePID();
2790 cuts->SetUsePID(kTRUE);
2791 if(cuts->IsSelectedPID(rd))
2792 rd->SetSelectionBit(bit);
2793 cuts->SetUsePID(usepid);
2797 //-----------------------------------------------------------------------------
2798 Bool_t AliAnalysisVertexingHF::SingleTrkCuts(AliESDtrack *trk,
2799 Float_t centralityperc,
2800 Bool_t &okDisplaced,
2802 Bool_t &okFor3Prong) const
2804 // Check if track passes some kinematical cuts
2806 // this is needed to store the impact parameters
2807 //AliCodeTimerAuto("",0);
2809 trk->RelateToVertex(fV1,fBzkG,kVeryBig);
2813 // Track selection, displaced tracks -- 2 prong
2815 if(centralityperc>=0 && fMaxCentPercentileForTightCuts>=0
2816 && fTrackFilter2prongCentral && centralityperc<fMaxCentPercentileForTightCuts){
2817 // central PbPb events, tighter cuts
2818 selectInfo = fTrackFilter2prongCentral->IsSelected(trk);
2822 selectInfo = fTrackFilter->IsSelected(trk);
2825 if(selectInfo) okDisplaced=kTRUE;
2827 // Track selection, displaced tracks -- 3 prong
2829 if(centralityperc>=0 && fMaxCentPercentileForTightCuts>=0
2830 && fTrackFilter3prongCentral && centralityperc<fMaxCentPercentileForTightCuts){
2831 // central PbPb events, tighter cuts
2832 selectInfo = fTrackFilter3prongCentral->IsSelected(trk);
2836 selectInfo = fTrackFilter->IsSelected(trk);
2839 if(selectInfo) okFor3Prong=kTRUE;
2841 // Track selection, soft pions
2843 if(fDstar && fTrackFilterSoftPi) {
2844 selectInfo = fTrackFilterSoftPi->IsSelected(trk);
2846 if(selectInfo) okSoftPi=kTRUE;
2848 if(okDisplaced || okSoftPi || okFor3Prong) return kTRUE;
2854 //-----------------------------------------------------------------------------
2855 AliAODv0* AliAnalysisVertexingHF::TransformESDv0toAODv0(AliESDv0 *esdV0, TObjArray *twoTrackArrayV0){
2857 // Transform ESDv0 to AODv0
2859 // this function takes the ESDv0 vertex, computes the DCA variables from the ESDv0
2860 // and creates an AODv0 out of them
2862 //AliCodeTimerAuto("",0);
2863 Double_t vertex[3]; esdV0->GetXYZ(vertex[0],vertex[1],vertex[2]);
2864 AliAODVertex *vertexV0 = new AliAODVertex(vertex,esdV0->GetChi2V0(),AliAODVertex::kV0,2);
2866 // create the v0 neutral track to compute the DCA to the primary vertex
2867 Double_t xyz[3], pxpypz[3];
2869 esdV0->PxPyPz(pxpypz);
2870 Double_t cv[21]; for(int i=0; i<21; i++) cv[i]=0;
2871 AliNeutralTrackParam *trackesdV0 = new AliNeutralTrackParam(xyz,pxpypz,cv,0);
2876 Double_t d0z0[2],covd0z0[3];
2877 AliAODVertex *primVertexAOD = PrimaryVertex();
2878 trackesdV0->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2879 Double_t dcaV0ToPrimVertex = TMath::Sqrt(covd0z0[0]);
2880 // get the v0 daughters to compute their DCA to the v0 vertex and get their momentum
2881 Double_t dcaV0DaughterToPrimVertex[2];
2882 AliExternalTrackParam *posV0track = (AliExternalTrackParam*)twoTrackArrayV0->UncheckedAt(0);
2883 AliExternalTrackParam *negV0track = (AliExternalTrackParam*)twoTrackArrayV0->UncheckedAt(1);
2884 if( !posV0track || !negV0track) {
2885 if(trackesdV0) {delete trackesdV0; trackesdV0=NULL;}
2887 delete primVertexAOD;
2890 posV0track->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2891 // if ( covd0z0[0]<=0.) dcaV0DaughterToPrimVertex[0] = 0;
2893 dcaV0DaughterToPrimVertex[0] = TMath::Sqrt(covd0z0[0]);
2894 negV0track->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2895 // if ( covd0z0[0]<=0.)dcaV0DaughterToPrimVertex[1] = 0;
2897 dcaV0DaughterToPrimVertex[1] = TMath::Sqrt(covd0z0[0]);
2898 Double_t dcaV0Daughters = esdV0->GetDcaV0Daughters();
2899 Double_t pmom[3],nmom[3];
2900 esdV0->GetNPxPyPz(nmom[0],nmom[1],nmom[2]);
2901 esdV0->GetPPxPyPz(pmom[0],pmom[1],pmom[2]);
2903 AliAODv0 *aodV0 = new AliAODv0(vertexV0,dcaV0Daughters,dcaV0ToPrimVertex,pmom,nmom,dcaV0DaughterToPrimVertex);
2904 aodV0->SetOnFlyStatus(esdV0->GetOnFlyStatus());
2907 delete primVertexAOD;
2911 //-----------------------------------------------------------------------------
2912 void AliAnalysisVertexingHF::SetParametersAtVertex(AliESDtrack* esdt, const AliExternalTrackParam* extpar) const{
2913 // Set the stored track parameters at primary vertex into AliESDtrack
2914 //AliCodeTimerAuto("",0);
2916 const Double_t *par=extpar->GetParameter();
2917 const Double_t *cov=extpar->GetCovariance();
2918 Double_t alpha=extpar->GetAlpha();
2919 Double_t x=extpar->GetX();
2920 esdt->Set(x,alpha,par,cov);
2923 //-----------------------------------------------------------------------------
2924 void AliAnalysisVertexingHF::SetMasses(){
2925 // Set the hadron mass values from TDatabasePDG
2927 fMassDzero=TDatabasePDG::Instance()->GetParticle(421)->Mass();
2928 fMassDplus=TDatabasePDG::Instance()->GetParticle(411)->Mass();
2929 fMassDs=TDatabasePDG::Instance()->GetParticle(431)->Mass();
2930 fMassLambdaC=TDatabasePDG::Instance()->GetParticle(4122)->Mass();
2931 fMassDstar=TDatabasePDG::Instance()->GetParticle(413)->Mass();
2932 fMassJpsi=TDatabasePDG::Instance()->GetParticle(443)->Mass();
2934 //-----------------------------------------------------------------------------
2935 Bool_t AliAnalysisVertexingHF::CheckCutsConsistency(){
2937 // Check the Vertexer and the analysts task consitstecny
2941 //___ Check if the V0 type from AliRDHFCutsLctoV0 is the same as the one set in the ConfigVertexingHF.C for AliAnalysisVertexingHF
2944 if ( fCutsLctoV0 && fV0TypeForCascadeVertex != fCutsLctoV0->GetV0Type())
2946 printf("ERROR: V0 type doesn not match in AliAnalysisVertexingHF (%d) required in AliRDHFCutsLctoV0 (%d)\n",fV0TypeForCascadeVertex,fCutsLctoV0->GetV0Type());
2951 //-----------------------------------------------------------------------------