AliPhysics  master (3d17d9d)
AliAnalysisVertexingHF.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3  * *
4  * Author: The ALICE Off-line Project. *
5  * Contributors are mentioned in the code where appropriate. *
6  * *
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  **************************************************************************/
15 
16 /* $Id$ */
17 
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.
24 //
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>
30 #include <TFile.h>
31 #include <TDatabasePDG.h>
32 #include <TString.h>
33 #include <TList.h>
34 #include <TProcessID.h>
35 #include "AliLog.h"
36 #include "AliVEvent.h"
37 #include "AliVVertex.h"
38 #include "AliVTrack.h"
39 #include "AliVertexerTracks.h"
40 #include "AliKFVertex.h"
41 #include "AliESDEvent.h"
42 #include "AliESDVertex.h"
43 #include "AliExternalTrackParam.h"
44 #include "AliNeutralTrackParam.h"
45 #include "AliESDtrack.h"
46 #include "AliESDtrackCuts.h"
47 #include "AliAODEvent.h"
48 #include "AliPIDResponse.h"
49 #include "AliAODRecoDecay.h"
50 #include "AliAODRecoDecayHF.h"
54 #include "AliAODRecoCascadeHF.h"
55 #include "AliRDHFCutsD0toKpi.h"
56 #include "AliRDHFCutsJpsitoee.h"
59 #include "AliRDHFCutsDstoK0sK.h"
60 #include "AliRDHFCutsDstoKKpi.h"
61 #include "AliRDHFCutsLctopKpi.h"
62 #include "AliRDHFCutsLctoV0.h"
63 #include "AliRDHFCutsD0toKpipipi.h"
65 #include "AliAnalysisFilter.h"
66 #include "AliAnalysisVertexingHF.h"
67 #include "AliMixedEvent.h"
68 #include "AliESDv0.h"
69 #include "AliAODv0.h"
70 #include "AliCodeTimer.h"
71 #include "AliMultSelection.h"
72 #include <cstring>
73 
75 ClassImp(AliAnalysisVertexingHF);
77 
78 //----------------------------------------------------------------------------
80 fInputAOD(kFALSE),
81 fAODMapSize(0),
82 fAODMap(0),
83 fVertexerTracks(0x0),
84 fBzkG(0.),
85 fSecVtxWithKF(kFALSE),
86 fRecoPrimVtxSkippingTrks(kFALSE),
87 fRmTrksFromPrimVtx(kFALSE),
88 fV1(0x0),
89 fV1AOD(0x0),
90 fD0toKpi(kTRUE),
91 fJPSItoEle(kTRUE),
92 f3Prong(kTRUE),
93 f4Prong(kTRUE),
94 fDstar(kTRUE),
95 fCascades(kTRUE),
96 fLikeSign(kFALSE),
97 fLikeSign3prong(kFALSE),
98 fMixEvent(kFALSE),
99 fPidResponse(0x0),
100 fUseKaonPIDfor3Prong(kFALSE),
101 fUsePIDforLc(0),
102 fUsePIDforLc2V0(0),
103 fUseKaonPIDforDs(kFALSE),
104 fUseTPCPID(kFALSE),
105 fUseTOFPID(kFALSE),
106 fUseTPCPIDOnlyIfNoTOF(kFALSE),
107 fMaxMomForTPCPid(1.),
108 fUsePidTag(kFALSE),
109 fnSigmaTPCPionLow(5.),
110 fnSigmaTPCPionHi(5.),
111 fnSigmaTOFPionLow(5.),
112 fnSigmaTOFPionHi(5.),
113 fnSigmaTPCKaonLow(5.),
114 fnSigmaTPCKaonHi(5.),
115 fnSigmaTOFKaonLow(5.),
116 fnSigmaTOFKaonHi(5.),
117 fnSigmaTPCProtonLow(5.),
118 fnSigmaTPCProtonHi(5.),
119 fnSigmaTOFProtonLow(5.),
120 fnSigmaTOFProtonHi(5.),
121 fMaxCentPercentileForTightCuts(-9999),
122 fTrackFilter(0x0),
123 fTrackFilter2prongCentral(0x0),
124 fTrackFilter3prongCentral(0x0),
125 fTrackFilterSoftPi(0x0),
126 fTrackFilterBachelor(0x0),
127 fCutsD0toKpi(0x0),
128 fCutsJpsitoee(0x0),
129 fCutsDplustoK0spi(0x0),
130 fCutsDplustoKpipi(0x0),
131 fCutsDstoK0sK(0x0),
132 fCutsDstoKKpi(0x0),
133 fCutsLctopKpi(0x0),
134 fCutsLctoV0(0x0),
135 fCutsD0toKpipipi(0x0),
136 fCutsDStartoKpipi(0x0),
137 fListOfCuts(0x0),
138 fFindVertexForDstar(kTRUE),
139 fFindVertexForCascades(kTRUE),
140 fV0TypeForCascadeVertex(0),
141 fMassCutBeforeVertexing(kFALSE),
142 fMassCalc2(0),
143 fMassCalc3(0),
144 fMassCalc4(0),
145 fMinPt3Prong(0.),
146 fOKInvMassD0(kFALSE),
147 fOKInvMassJpsi(kFALSE),
148 fOKInvMassDplus(kFALSE),
149 fOKInvMassDs(kFALSE),
150 fOKInvMassLc(kFALSE),
151 fOKInvMassDstar(kFALSE),
152 fOKInvMassD0to4p(kFALSE),
153 fOKInvMassLctoV0(kFALSE),
154 fnTrksTotal(0),
155 fnSeleTrksTotal(0),
156 fMakeReducedRHF(kFALSE),
157 fMassDzero(0.),
158 fMassDplus(0.),
159 fMassDs(0.),
160 fMassLambdaC(0.),
161 fMassDstar(0.),
162 fMassJpsi(0.),
163 fMassPhi(0.),
164 fMassK(0.)
165 {
167 
168  Double_t d02[2]={0.,0.};
169  Double_t d03[3]={0.,0.,0.};
170  Double_t d04[4]={0.,0.,0.,0.};
171  fMassCalc2 = new AliAODRecoDecay(0x0,2,0,d02);
172  fMassCalc3 = new AliAODRecoDecay(0x0,3,1,d03);
173  fMassCalc4 = new AliAODRecoDecay(0x0,4,0,d04);
174  SetMasses();
175 }
176 //--------------------------------------------------------------------------
178 TNamed(source),
179 fInputAOD(source.fInputAOD),
180 fAODMapSize(source.fAODMapSize),
181 fAODMap(source.fAODMap),
183 fBzkG(source.fBzkG),
187 fV1(source.fV1),
188 fV1AOD(source.fV1AOD),
189 fD0toKpi(source.fD0toKpi),
190 fJPSItoEle(source.fJPSItoEle),
191 f3Prong(source.f3Prong),
192 f4Prong(source.f4Prong),
193 fDstar(source.fDstar),
194 fCascades(source.fCascades),
195 fLikeSign(source.fLikeSign),
197 fMixEvent(source.fMixEvent),
198 fPidResponse(source.fPidResponse),
200 fUsePIDforLc(source.fUsePIDforLc),
203 fUseTPCPID(source.fUseTPCPID),
204 fUseTOFPID(source.fUseTOFPID),
207 fUsePidTag(source.fUsePidTag),
221 fTrackFilter(source.fTrackFilter),
226 fCutsD0toKpi(source.fCutsD0toKpi),
233 fCutsLctoV0(source.fCutsLctoV0),
236 fListOfCuts(source.fListOfCuts),
241 fMassCalc2(source.fMassCalc2),
242 fMassCalc3(source.fMassCalc3),
243 fMassCalc4(source.fMassCalc4),
244 fMinPt3Prong(source.fMinPt3Prong),
245 fOKInvMassD0(source.fOKInvMassD0),
248 fOKInvMassDs(source.fOKInvMassDs),
249 fOKInvMassLc(source.fOKInvMassLc),
253 fnTrksTotal(0),
254 fnSeleTrksTotal(0),
255 fMakeReducedRHF(kFALSE),
256 fMassDzero(source.fMassDzero),
257 fMassDplus(source.fMassDplus),
258 fMassDs(source.fMassDs),
259 fMassLambdaC(source.fMassLambdaC),
260 fMassDstar(source.fMassDstar),
261 fMassJpsi(source.fMassJpsi),
262 fMassPhi(source.fMassPhi),
263 fMassK(source.fMassK)
264 {
268 }
269 //--------------------------------------------------------------------------
271 {
275  if(&source == this) return *this;
276  fInputAOD = source.fInputAOD;
277  fAODMapSize = source.fAODMapSize;
279  fBzkG = source.fBzkG;
280  fSecVtxWithKF = source.fSecVtxWithKF;
283  fV1 = source.fV1;
284  fV1AOD =source.fV1AOD;
285  fD0toKpi = source.fD0toKpi;
286  fJPSItoEle = source.fJPSItoEle;
287  f3Prong = source.f3Prong;
288  f4Prong = source.f4Prong;
289  fDstar = source.fDstar;
290  fCascades = source.fCascades;
291  fLikeSign = source.fLikeSign;
293  fMixEvent = source.fMixEvent;
294  fPidResponse = source.fPidResponse;
296  fUsePIDforLc = source.fUsePIDforLc;
299  fUseTPCPID = source.fUseTPCPID;
300  fUseTOFPID = source.fUseTOFPID;
303  fUsePidTag = source.fUsePidTag;
319  fTrackFilter = source.fTrackFilter;
324  fCutsD0toKpi = source.fCutsD0toKpi;
325  fCutsJpsitoee = source.fCutsJpsitoee;
328  fCutsDstoK0sK = source.fCutsDstoK0sK;
329  fCutsDstoKKpi = source.fCutsDstoKKpi;
330  fCutsLctopKpi = source.fCutsLctopKpi;
331  fCutsLctoV0 = source.fCutsLctoV0;
334  fListOfCuts = source.fListOfCuts;
339  fMassCalc2 = source.fMassCalc2;
340  fMassCalc3 = source.fMassCalc3;
341  fMassCalc4 = source.fMassCalc4;
342  fMinPt3Prong = source.fMinPt3Prong;
343  fOKInvMassD0 = source.fOKInvMassD0;
346  fOKInvMassDs = source.fOKInvMassDs;
347  fOKInvMassLc = source.fOKInvMassLc;
351  fMassDzero = source.fMassDzero;
352  fMassDplus = source.fMassDplus;
353  fMassDs = source.fMassDs;
354  fMassLambdaC = source.fMassLambdaC;
355  fMassDstar = source.fMassDstar;
356  fMassJpsi = source.fMassJpsi;
357  fMassPhi = source.fMassPhi;
358  fMassK = source.fMassK;
359 
360  return *this;
361 }
362 //----------------------------------------------------------------------------
365  if(fV1) { delete fV1; fV1=0; }
366  if(fV1AOD) { delete fV1AOD; fV1AOD=0; }
367  delete fVertexerTracks;
368  if(fTrackFilter) { delete fTrackFilter; fTrackFilter=0; }
373  if(fCutsD0toKpi) { delete fCutsD0toKpi; fCutsD0toKpi=0; }
374  if(fCutsJpsitoee) { delete fCutsJpsitoee; fCutsJpsitoee=0; }
377  if(fCutsDstoK0sK) { delete fCutsDstoK0sK; fCutsDstoK0sK=0; }
378  if(fCutsDstoKKpi) { delete fCutsDstoKKpi; fCutsDstoKKpi=0; }
379  if(fCutsLctopKpi) { delete fCutsLctopKpi; fCutsLctopKpi=0; }
380  if(fCutsLctoV0) { delete fCutsLctoV0; fCutsLctoV0=0; }
383  if(fAODMap) { delete [] fAODMap; fAODMap=0; }
384  if(fMassCalc2) { delete fMassCalc2; fMassCalc2=0; }
385  if(fMassCalc3) { delete fMassCalc3; fMassCalc3=0; }
386  if(fMassCalc4) { delete fMassCalc4; fMassCalc4=0; }
387 }
388 //----------------------------------------------------------------------------
391 
392  TList *list = new TList();
393  list->SetOwner();
394  list->SetName("ListOfCuts");
395 
396  if(fCutsD0toKpi) {
398  list->Add(cutsD0toKpi);
399  }
400  if(fCutsJpsitoee) {
402  list->Add(cutsJpsitoee);
403  }
404  if (fCutsDplustoK0spi) {
406  list->Add(cutsDplustoK0spi);
407  }
408  if(fCutsDplustoKpipi) {
410  list->Add(cutsDplustoKpipi);
411  }
412  if (fCutsDstoK0sK) {
414  list->Add(cutsDstoK0sK);
415  }
416  if(fCutsDstoKKpi) {
418  list->Add(cutsDstoKKpi);
419  }
420  if(fCutsLctopKpi) {
422  list->Add(cutsLctopKpi);
423  }
424  if(fCutsLctoV0){
425  AliRDHFCutsLctoV0 *cutsLctoV0 = new AliRDHFCutsLctoV0(*fCutsLctoV0);
426  list->Add(cutsLctoV0);
427  }
428  if(fCutsD0toKpipipi) {
430  list->Add(cutsD0toKpipipi);
431  }
432  if(fCutsDStartoKpipi) {
434  list->Add(cutsDStartoKpipi);
435  }
436 
437  //___ Check consitstency of cuts between vertexer and analysis tasks
438  Bool_t bCutsOk = CheckCutsConsistency();
439  if (bCutsOk == kFALSE) {AliFatal("AliAnalysisVertexingHF::FillListOfCuts vertexing and the analysis task cuts are not consistent!");}
440 
441  // keep a pointer to the list
442  fListOfCuts = list;
443 
444  return list;
445 }
446 //----------------------------------------------------------------------------
448  TClonesArray *aodVerticesHFTClArr,
449  TClonesArray *aodD0toKpiTClArr,
450  TClonesArray *aodJPSItoEleTClArr,
451  TClonesArray *aodCharm3ProngTClArr,
452  TClonesArray *aodCharm4ProngTClArr,
453  TClonesArray *aodDstarTClArr,
454  TClonesArray *aodCascadesTClArr,
455  TClonesArray *aodLikeSign2ProngTClArr,
456  TClonesArray *aodLikeSign3ProngTClArr)
457 {
461  //AliCodeTimerAuto("",0);
462 
463  if(!fMixEvent){
464  TString evtype = event->IsA()->GetName();
465  fInputAOD = ((evtype=="AliAODEvent") ? kTRUE : kFALSE);
466  } // if we do mixing AliVEvent is a AliMixedEvent
467 
468  if(fInputAOD) {
469  AliDebug(2,"Creating HF candidates from AOD");
470  } else {
471  AliDebug(2,"Creating HF candidates from ESD");
472  }
473 
474  if(!aodVerticesHFTClArr) {
475  printf("ERROR: no aodVerticesHFTClArr");
476  return;
477  }
478  if((fD0toKpi || fDstar) && !aodD0toKpiTClArr) {
479  printf("ERROR: no aodD0toKpiTClArr");
480  return;
481  }
482  if(fJPSItoEle && !aodJPSItoEleTClArr) {
483  printf("ERROR: no aodJPSItoEleTClArr");
484  return;
485  }
486  if(f3Prong && !aodCharm3ProngTClArr) {
487  printf("ERROR: no aodCharm3ProngTClArr");
488  return;
489  }
490  if(f4Prong && !aodCharm4ProngTClArr) {
491  printf("ERROR: no aodCharm4ProngTClArr");
492  return;
493  }
494  if(fDstar && !aodDstarTClArr) {
495  printf("ERROR: no aodDstarTClArr");
496  return;
497  }
498  if(fCascades && !aodCascadesTClArr){
499  printf("ERROR: no aodCascadesTClArr ");
500  return;
501  }
502  if(fLikeSign && !aodLikeSign2ProngTClArr) {
503  printf("ERROR: no aodLikeSign2ProngTClArr");
504  return;
505  }
506  if(fLikeSign3prong && f3Prong && !aodLikeSign3ProngTClArr) {
507  printf("ERROR: no aodLikeSign3ProngTClArr");
508  return;
509  }
510 
511  // delete candidates from previous event and create references
512  Int_t iVerticesHF=0,iD0toKpi=0,iJPSItoEle=0,i3Prong=0,i4Prong=0,iDstar=0,iCascades=0,iLikeSign2Prong=0,iLikeSign3Prong=0;
513  aodVerticesHFTClArr->Delete();
514  iVerticesHF = aodVerticesHFTClArr->GetEntriesFast();
515  TClonesArray &verticesHFRef = *aodVerticesHFTClArr;
516  if(fD0toKpi || fDstar) {
517  aodD0toKpiTClArr->Delete();
518  iD0toKpi = aodD0toKpiTClArr->GetEntriesFast();
519  }
520  if(fJPSItoEle) {
521  aodJPSItoEleTClArr->Delete();
522  iJPSItoEle = aodJPSItoEleTClArr->GetEntriesFast();
523  }
524  if(f3Prong) {
525  aodCharm3ProngTClArr->Delete();
526  i3Prong = aodCharm3ProngTClArr->GetEntriesFast();
527  }
528  if(f4Prong) {
529  aodCharm4ProngTClArr->Delete();
530  i4Prong = aodCharm4ProngTClArr->GetEntriesFast();
531  }
532  if(fDstar) {
533  aodDstarTClArr->Delete();
534  iDstar = aodDstarTClArr->GetEntriesFast();
535  }
536  if(fCascades) {
537  aodCascadesTClArr->Delete();
538  iCascades = aodCascadesTClArr->GetEntriesFast();
539  }
540  if(fLikeSign) {
541  aodLikeSign2ProngTClArr->Delete();
542  iLikeSign2Prong = aodLikeSign2ProngTClArr->GetEntriesFast();
543  }
544  if(fLikeSign3prong && f3Prong) {
545  aodLikeSign3ProngTClArr->Delete();
546  iLikeSign3Prong = aodLikeSign3ProngTClArr->GetEntriesFast();
547  }
548 
549  TClonesArray &aodD0toKpiRef = *aodD0toKpiTClArr;
550  TClonesArray &aodJPSItoEleRef = *aodJPSItoEleTClArr;
551  TClonesArray &aodCharm3ProngRef = *aodCharm3ProngTClArr;
552  TClonesArray &aodCharm4ProngRef = *aodCharm4ProngTClArr;
553  TClonesArray &aodDstarRef = *aodDstarTClArr;
554  TClonesArray &aodCascadesRef = *aodCascadesTClArr;
555  TClonesArray &aodLikeSign2ProngRef = *aodLikeSign2ProngTClArr;
556  TClonesArray &aodLikeSign3ProngRef = *aodLikeSign3ProngTClArr;
557 
558 
559  AliAODRecoDecayHF2Prong *io2Prong = 0;
560  AliAODRecoDecayHF3Prong *io3Prong = 0;
561  AliAODRecoDecayHF4Prong *io4Prong = 0;
562  AliAODRecoCascadeHF *ioCascade = 0;
563 
564  Int_t iTrkP1,iTrkP2,iTrkN1,iTrkN2,iTrkSoftPi,trkEntries,iv0,nv0;
565  Double_t xdummy,ydummy,dcap1n1,dcap1n2,dcap2n1,dcap1p2,dcan1n2,dcap2n2,dcaCasc;
566  Bool_t okD0=kFALSE,okJPSI=kFALSE,ok3Prong=kFALSE,ok4Prong=kFALSE;
567  Bool_t okDstar=kFALSE,okD0fromDstar=kFALSE;
568  Bool_t okCascades=kFALSE;
569  AliESDtrack *postrack1 = 0;
570  AliESDtrack *postrack2 = 0;
571  AliESDtrack *negtrack1 = 0;
572  AliESDtrack *negtrack2 = 0;
573  AliESDtrack *trackPi = 0;
574  Double_t mompos1[3],mompos2[3],momneg1[3],momneg2[3];
575  Float_t dcaMax = fCutsD0toKpi->GetDCACut();
576  if(fCutsJpsitoee) dcaMax=TMath::Max(dcaMax,fCutsJpsitoee->GetDCACut());
577  if(fCutsDplustoKpipi) dcaMax=TMath::Max(dcaMax,fCutsDplustoKpipi->GetDCACut());
578  if(fCutsDstoKKpi) dcaMax=TMath::Max(dcaMax,fCutsDstoKKpi->GetDCACut());
579  if(fCutsLctopKpi) dcaMax=TMath::Max(dcaMax,fCutsLctopKpi->GetDCACut());
580  if(fCutsD0toKpipipi) dcaMax=TMath::Max(dcaMax,fCutsD0toKpipipi->GetDCACut());
581  if(fCutsDStartoKpipi) dcaMax=TMath::Max(dcaMax,fCutsDStartoKpipi->GetDCACut());
582 
583  AliDebug(2,Form(" dca cut set to %f cm",dcaMax));
584 
585 
586  // get Bz
587  fBzkG = (Double_t)event->GetMagneticField();
588  if(!fVertexerTracks){
589  fVertexerTracks=new AliVertexerTracks(fBzkG);
590  }else{
591  Double_t oldField=fVertexerTracks->GetFieldkG();
592  if(oldField!=fBzkG) fVertexerTracks->SetFieldkG(fBzkG);
593  }
594 
595  trkEntries = (Int_t)event->GetNumberOfTracks();
596  AliDebug(1,Form(" Number of tracks: %d",trkEntries));
597  fnTrksTotal += trkEntries;
598 
599  nv0 = (Int_t)event->GetNumberOfV0s();
600  AliDebug(1,Form(" Number of V0s: %d",nv0));
601 
602  if( trkEntries<2 && (trkEntries<1 || nv0<1) ) {
603  AliDebug(1,Form(" Not enough tracks: %d",trkEntries));
604  return;
605  }
606 
607  // event selection + PID configuration
608  if(!fCutsD0toKpi->IsEventSelected(event)) return;
615  if(fCutsLctoV0) fCutsLctoV0->SetupPID(event);
618 
619  // call function that applies sigle-track selection,
620  // for displaced tracks and soft pions (both charges) for D*,
621  // and retrieves primary vertex
622  TObjArray seleTrksArray(trkEntries);
623  TObjArray tracksAtVertex(trkEntries);
624  UChar_t *seleFlags = new UChar_t[trkEntries]; // bit 0: displaced, bit 1: softpi, bit 2: 3 prong, bits 3-4-5: for PID
625  Int_t nSeleTrks=0;
626  Int_t *evtNumber = new Int_t[trkEntries];
627  SelectTracksAndCopyVertex(event,trkEntries,seleTrksArray,tracksAtVertex,nSeleTrks,seleFlags,evtNumber);
628 
629  AliDebug(1,Form(" Selected tracks: %d",nSeleTrks));
630  fnSeleTrksTotal += nSeleTrks;
631 
632 
633  TObjArray *twoTrackArray1 = new TObjArray(2);
634  TObjArray *twoTrackArray2 = new TObjArray(2);
635  TObjArray *twoTrackArrayV0 = new TObjArray(2);
636  TObjArray *twoTrackArrayCasc = new TObjArray(2);
637  TObjArray *threeTrackArray = new TObjArray(3);
638  TObjArray *fourTrackArray = new TObjArray(4);
639 
640  Double_t dispersion;
641  Bool_t isLikeSign2Prong=kFALSE,isLikeSign3Prong=kFALSE;
642 
643  AliAODRecoDecayHF *rd = 0;
644  AliAODRecoCascadeHF *rc = 0;
645  AliAODv0 *v0 = 0;
646  AliESDv0 *esdV0 = 0;
647 
648  Bool_t massCutOK=kTRUE;
649 
650  fMinPt3Prong=0.;
652  fMinPt3Prong=TMath::Min(fMinPt3Prong,fCutsLctopKpi->GetMinPtCandidate());
653 
654  Double_t minPtV0=0.;
655  if(fCutsLctoV0) minPtV0=fCutsLctoV0->GetMinV0PtCut();
656  if(fCutsDstoK0sK){
657  Double_t minPtV0fromDs=fCutsDstoK0sK->GetMinV0PtCut();
658  if(minPtV0fromDs<minPtV0) minPtV0=minPtV0fromDs;
659  }
660  if(fCutsDplustoK0spi){
661  Double_t minPtV0fromDp=fCutsDplustoK0spi->GetMinV0PtCut();
662  if(minPtV0fromDp<minPtV0) minPtV0=minPtV0fromDp;
663  }
664 
665  // LOOP ON POSITIVE TRACKS
666  for(iTrkP1=0; iTrkP1<nSeleTrks; iTrkP1++) {
667 
668  //if(iTrkP1%1==0) AliDebug(1,Form(" 1st loop on pos: track number %d of %d",iTrkP1,nSeleTrks));
669  //if(iTrkP1%1==0) printf(" 1st loop on pos: track number %d of %d\n",iTrkP1,nSeleTrks);
670 
671  // get track from tracks array
672  postrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP1);
673  postrack1->GetPxPyPz(mompos1);
674 
675  // Make cascades with V0+track
676  //
677  if(fCascades) {
678  // loop on V0's
679  for(iv0=0; iv0<nv0; iv0++){
680 
681  //AliDebug(1,Form(" loop on v0s for track number %d and v0 number %d",iTrkP1,iv0));
682  if ( !TESTBIT(seleFlags[iTrkP1],kBitBachelor) ) continue;
683 
684  if ( fUsePIDforLc2V0 && !TESTBIT(seleFlags[iTrkP1],kBitProtonCompat) ) continue; //clm
685 
686  // Get the V0
687  if(fInputAOD) {
688  v0 = ((AliAODEvent*)event)->GetV0(iv0);
689  } else {
690  esdV0 = ((AliESDEvent*)event)->GetV0(iv0);
691  }
692  if ( (!v0 || !v0->IsA()->InheritsFrom("AliAODv0") ) &&
693  (!esdV0 || !esdV0->IsA()->InheritsFrom("AliESDv0") ) ) continue;
694 
695  if ( v0 && ((v0->GetOnFlyStatus() == kTRUE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOfflineV0s) ||
696  (v0->GetOnFlyStatus() == kFALSE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOnTheFlyV0s)) ) continue;
697 
698  if ( esdV0 && ((esdV0->GetOnFlyStatus() == kTRUE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOfflineV0s) ||
699  ( esdV0->GetOnFlyStatus() == kFALSE && fV0TypeForCascadeVertex == AliRDHFCuts::kOnlyOnTheFlyV0s)) ) continue;
700 
701  if(v0->Pt()<minPtV0) continue;
702  // Get the tracks that form the V0
703  // ( parameters at primary vertex )
704  // and define an AliExternalTrackParam out of them
705 
706  if(fInputAOD){
707  AliAODTrack *posVV0track = (AliAODTrack*)(v0->GetDaughter(0));
708  AliAODTrack *negVV0track = (AliAODTrack*)(v0->GetDaughter(1));
709  if( !posVV0track || !negVV0track ) continue;
710  //
711  // Apply some basic V0 daughter criteria
712  //
713  // bachelor must not be a v0-track
714  if (posVV0track->GetID() == postrack1->GetID() ||
715  negVV0track->GetID() == postrack1->GetID()) continue;
716  // reject like-sign v0
717  if ( posVV0track->Charge() == negVV0track->Charge() ) continue;
718  // avoid ghost TPC tracks
719  if(!(posVV0track->GetStatus() & AliESDtrack::kTPCrefit) ||
720  !(negVV0track->GetStatus() & AliESDtrack::kTPCrefit)) continue;
721  } else {
722  AliESDtrack *posVV0track = (AliESDtrack*)(event->GetTrack( esdV0->GetPindex() ));
723  AliESDtrack *negVV0track = (AliESDtrack*)(event->GetTrack( esdV0->GetNindex() ));
724  if( !posVV0track || !negVV0track ) continue;
725  //
726  // Apply some basic V0 daughter criteria
727  //
728  // bachelor must not be a v0-track
729  if (posVV0track->GetID() == postrack1->GetID() ||
730  negVV0track->GetID() == postrack1->GetID()) continue;
731  // reject like-sign v0
732  if ( posVV0track->Charge() == negVV0track->Charge() ) continue;
733  // avoid ghost TPC tracks
734  if(!(posVV0track->GetStatus() & AliESDtrack::kTPCrefit) ||
735  !(negVV0track->GetStatus() & AliESDtrack::kTPCrefit)) continue;
736  // reject kinks (only necessary on AliESDtracks)
737  if (posVV0track->GetKinkIndex(0)>0 || negVV0track->GetKinkIndex(0)>0) continue;
738 
739  // Define the AODv0 from ESDv0 if reading ESDs
740  twoTrackArrayV0->AddAt(posVV0track,0);
741  twoTrackArrayV0->AddAt(negVV0track,1);
742  v0 = TransformESDv0toAODv0(esdV0,twoTrackArrayV0);
743  twoTrackArrayV0->Clear();
744  }
745 
746  // Define the V0 (neutral) track
747  AliNeutralTrackParam *trackV0=NULL;
748  if(fInputAOD) {
749  const AliVTrack *trackVV0 = dynamic_cast<const AliVTrack*>(v0);
750  if(trackVV0) trackV0 = new AliNeutralTrackParam(trackVV0);
751  } else {
752  Double_t xyz[3], pxpypz[3];
753  esdV0->XvYvZv(xyz);
754  esdV0->PxPyPz(pxpypz);
755  Double_t cv[21]; for(int i=0; i<21; i++) cv[i]=0;
756  trackV0 = new AliNeutralTrackParam(xyz,pxpypz,cv,0);
757  }
758 
759 
760  // Fill in the object array to create the cascade
761  twoTrackArrayCasc->AddAt(postrack1,0);
762  twoTrackArrayCasc->AddAt(trackV0,1);
764  Bool_t passMassCut = SelectInvMassAndPtCascade(twoTrackArrayCasc);
765  if(!passMassCut){
766  delete trackV0; trackV0=NULL;
767  if(!fInputAOD) {delete v0; v0=NULL;}
768  twoTrackArrayCasc->Clear();
769  continue;
770  }
771  }
772  // Compute the cascade vertex
773  AliAODVertex *vertexCasc = 0;
775  // DCA between the two tracks
776  dcaCasc = postrack1->GetDCA(trackV0,fBzkG,xdummy,ydummy);
777  // Vertexing+
778  vertexCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
779  } else {
780  // assume Cascade decays at the primary vertex
781  Double_t pos[3],cov[6],chi2perNDF;
782  fV1->GetXYZ(pos);
783  fV1->GetCovMatrix(cov);
784  chi2perNDF = fV1->GetChi2toNDF();
785  vertexCasc = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,2);
786  dcaCasc = 0.;
787  }
788  if(!vertexCasc) {
789  delete trackV0; trackV0=NULL;
790  if(!fInputAOD) {delete v0; v0=NULL;}
791  twoTrackArrayCasc->Clear();
792  continue;
793  }
794 
795  // Create and store the Cascade if passed the cuts
796  ioCascade = MakeCascade(twoTrackArrayCasc,event,vertexCasc,v0,dcaCasc,okCascades);
797  if(okCascades && ioCascade) {
798  //AliDebug(1,Form("Storing a cascade object... "));
799  // add the vertex and the cascade to the AOD
800  rc = new(aodCascadesRef[iCascades++])AliAODRecoCascadeHF(*ioCascade);
801  if(fMakeReducedRHF){
802  UShort_t id[2]={(UShort_t)postrack1->GetID(),(UShort_t)iv0};
803  rc->SetProngIDs(2,id);
804  rc->DeleteRecoD();
805  }else{
806  AliAODVertex *vCasc = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexCasc);
807  rc->SetSecondaryVtx(vCasc);
808  vCasc->SetParent(rc);
809  if(!fInputAOD) vCasc->AddDaughter(v0); // just to fill ref #0 ??
810  AddRefs(vCasc,rc,event,twoTrackArrayCasc); // add the track (proton)
811  vCasc->AddDaughter(v0); // fill the 2prong V0
812  }
813  rc->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
814  }
815 
816 
817  // Clean up
818  delete trackV0; trackV0=NULL;
819  twoTrackArrayCasc->Clear();
820  if(ioCascade) { delete ioCascade; ioCascade=NULL; }
821  if(vertexCasc) { delete vertexCasc; vertexCasc=NULL; }
822  if(!fInputAOD) {delete v0; v0=NULL;}
823 
824  } // end loop on V0's
825 
826  // re-set parameters at vertex
827  SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
828  } // end fCascades
829 
830  // If there is less than 2 particles continue
831  if(trkEntries<2) {
832  AliDebug(1,Form(" Not enough tracks: %d",trkEntries));
833  continue;
834  }
835 
836  if(!TESTBIT(seleFlags[iTrkP1],kBitDispl)) continue;
837  if(postrack1->Charge()<0 && !fLikeSign) continue;
838 
839  // LOOP ON NEGATIVE TRACKS
840  for(iTrkN1=0; iTrkN1<nSeleTrks; iTrkN1++) {
841 
842  //if(iTrkN1%1==0) AliDebug(1,Form(" 1st loop on neg: track number %d of %d",iTrkN1,nSeleTrks));
843  //if(iTrkN1%1==0) printf(" 1st loop on neg: track number %d of %d\n",iTrkN1,nSeleTrks);
844 
845  if(iTrkN1==iTrkP1) continue;
846 
847  // get track from tracks array
848  negtrack1 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN1);
849 
850  if(negtrack1->Charge()>0 && !fLikeSign) continue;
851 
852  if(!TESTBIT(seleFlags[iTrkN1],kBitDispl)) continue;
853 
854  if(fMixEvent) {
855  if(evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
856  }
857 
858  if(postrack1->Charge()==negtrack1->Charge()) { // like-sign
859  isLikeSign2Prong=kTRUE;
860  if(!fLikeSign) continue;
861  if(iTrkN1<iTrkP1) continue; // this is needed to avoid double-counting of like-sign
862  } else { // unlike-sign
863  isLikeSign2Prong=kFALSE;
864  if(postrack1->Charge()<0 || negtrack1->Charge()>0) continue; // this is needed to avoid double-counting of unlike-sign
865  if(fMixEvent) {
866  if(evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
867  }
868 
869  }
870 
871  // back to primary vertex
872  // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
873  // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
874  SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
875  SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
876  negtrack1->GetPxPyPz(momneg1);
877 
878  // DCA between the two tracks
879  dcap1n1 = postrack1->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
880  if(dcap1n1>dcaMax) { negtrack1=0; continue; }
881 
882  // Vertexing
883  twoTrackArray1->AddAt(postrack1,0);
884  twoTrackArray1->AddAt(negtrack1,1);
885  AliAODVertex *vertexp1n1 = ReconstructSecondaryVertex(twoTrackArray1,dispersion);
886  if(!vertexp1n1) {
887  twoTrackArray1->Clear();
888  negtrack1=0;
889  continue;
890  }
891  // 2 prong candidate
892  if(fD0toKpi || fJPSItoEle || fDstar || fLikeSign) {
893 
894  io2Prong = Make2Prong(twoTrackArray1,event,vertexp1n1,dcap1n1,okD0,okJPSI,okD0fromDstar);
895 
896  if((fD0toKpi && okD0) || (fJPSItoEle && okJPSI) || (isLikeSign2Prong && (okD0 || okJPSI))) {
897  // add the vertex and the decay to the AOD
898  AliAODVertex *v2Prong =0x0;
899  if(!fMakeReducedRHF)v2Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
900  if(!isLikeSign2Prong) {
901  if(okD0) {
902  rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
904 
905  if(fMakeReducedRHF){
906  rd->DeleteRecoD();
907  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
908  }else{
909  rd->SetSecondaryVtx(v2Prong);
910  v2Prong->SetParent(rd);
911  AddRefs(v2Prong,rd,event,twoTrackArray1);
912  }
913  }
914  if(okJPSI) {
915  rd = new(aodJPSItoEleRef[iJPSItoEle++])AliAODRecoDecayHF2Prong(*io2Prong);
916  if(fMakeReducedRHF){
917  rd->DeleteRecoD();
918  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
919  }else{
920  if(!okD0) v2Prong->SetParent(rd); // it cannot have two mothers ...
921  AddRefs(v2Prong,rd,event,twoTrackArray1);
922  }
923  }
924  } else { // isLikeSign2Prong
925  rd = new(aodLikeSign2ProngRef[iLikeSign2Prong++])AliAODRecoDecayHF2Prong(*io2Prong);
926  //Set selection bit for PID
928  if(fMakeReducedRHF){
929  rd->DeleteRecoD();
930  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
931  }else{
932  rd->SetSecondaryVtx(v2Prong);
933  v2Prong->SetParent(rd);
934  AddRefs(v2Prong,rd,event,twoTrackArray1);
935  }
936  }
937  }
938  // D* candidates
939  if(fDstar && okD0fromDstar && !isLikeSign2Prong) {
940  // write references in io2Prong
941  if(fInputAOD) {
942  AddDaughterRefs(vertexp1n1,event,twoTrackArray1);
943  } else {
944  vertexp1n1->AddDaughter(postrack1);
945  vertexp1n1->AddDaughter(negtrack1);
946  }
947  io2Prong->SetSecondaryVtx(vertexp1n1);
948  //printf("---> %d %d %d %d %d\n",vertexp1n1->GetNDaughters(),iTrkP1,iTrkN1,postrack1->Charge(),negtrack1->Charge());
949  // create a track from the D0
950  AliNeutralTrackParam *trackD0 = new AliNeutralTrackParam(io2Prong);
951 
952  // LOOP ON TRACKS THAT PASSED THE SOFT PION CUTS
953  for(iTrkSoftPi=0; iTrkSoftPi<nSeleTrks; iTrkSoftPi++) {
954 
955  if(iTrkSoftPi==iTrkP1 || iTrkSoftPi==iTrkN1) continue;
956 
957  if(!TESTBIT(seleFlags[iTrkSoftPi],kBitSoftPi)) continue;
958 
959  if(fMixEvent) {
960  if(evtNumber[iTrkP1]==evtNumber[iTrkSoftPi] ||
961  evtNumber[iTrkN1]==evtNumber[iTrkSoftPi] ||
962  evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
963  }
964 
965  //if(iTrkSoftPi%1==0) AliDebug(1,Form(" 1st loop on pi_s: track number %d of %d",iTrkSoftPi,nSeleTrks));
966 
967  trackD0->PropagateToDCA(fV1,fBzkG,kVeryBig);
968  if(trackD0->GetSigmaY2()<0. || trackD0->GetSigmaZ2()<0.) continue; // this is insipired by the AliITStrackV2::Invariant() checks
969 
970  // get track from tracks array
971  trackPi = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkSoftPi);
972  // trackPi->PropagateToDCA(fV1,fBzkG,kVeryBig);
973  SetParametersAtVertex(trackPi,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkSoftPi));
974  twoTrackArrayCasc->AddAt(trackPi,0);
975  twoTrackArrayCasc->AddAt(trackD0,1);
976  if(!SelectInvMassAndPtDstarD0pi(twoTrackArrayCasc)){
977  twoTrackArrayCasc->Clear();
978  trackPi=0;
979  continue;
980  }
981 
982  AliAODVertex *vertexCasc = 0;
983 
984  if(fFindVertexForDstar) {
985  // DCA between the two tracks
986  dcaCasc = trackPi->GetDCA(trackD0,fBzkG,xdummy,ydummy);
987  // Vertexing
988  vertexCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
989  } else {
990  // assume Dstar decays at the primary vertex
991  Double_t pos[3],cov[6],chi2perNDF;
992  fV1->GetXYZ(pos);
993  fV1->GetCovMatrix(cov);
994  chi2perNDF = fV1->GetChi2toNDF();
995  vertexCasc = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,2);
996  dcaCasc = 0.;
997  }
998  if(!vertexCasc) {
999  twoTrackArrayCasc->Clear();
1000  trackPi=0;
1001  continue;
1002  }
1003 
1004  ioCascade = MakeCascade(twoTrackArrayCasc,event,vertexCasc,io2Prong,dcaCasc,okDstar);
1005  if(okDstar) {
1006  // add the D0 to the AOD (if not already done)
1007  if(!okD0) {
1008  rd = new(aodD0toKpiRef[iD0toKpi++])AliAODRecoDecayHF2Prong(*io2Prong);
1009  if(fMakeReducedRHF){
1010  rd->DeleteRecoD();
1011  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1012  }else{
1013  AliAODVertex *v2Prong = new (verticesHFRef[iVerticesHF++])AliAODVertex(*vertexp1n1);
1014  rd->SetSecondaryVtx(v2Prong);
1015  v2Prong->SetParent(rd);
1016  AddRefs(v2Prong,rd,event,twoTrackArray1);
1017  }
1018  okD0=kTRUE; // this is done to add it only once
1019  }
1020  // add the vertex and the cascade to the AOD
1021  rc = new(aodDstarRef[iDstar++])AliAODRecoCascadeHF(*ioCascade);
1022  // Set selection bit for PID
1024  if(fMakeReducedRHF){
1025  //assign a ID to the D0 candidate, daughter of the Cascade. ID = position in the D0toKpi array
1026  UShort_t idCasc[2]={(UShort_t)trackPi->GetID(),(UShort_t)(iD0toKpi-1)};
1027  rc->SetProngIDs(2,idCasc);
1028  rc->DeleteRecoD();
1029  rc->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1030  }else{
1031  AliAODVertex *vCasc = new(verticesHFRef[iVerticesHF++])AliAODVertex(*vertexCasc);
1032  rc->SetSecondaryVtx(vCasc);
1033  vCasc->SetParent(rc);
1034  if(!fInputAOD) vCasc->AddDaughter(rd); // just to fill ref #0
1035  AddRefs(vCasc,rc,event,twoTrackArrayCasc);
1036  vCasc->AddDaughter(rd); // add the D0 (in ref #1)
1037  }
1038  }
1039  twoTrackArrayCasc->Clear();
1040  trackPi=0;
1041  if(ioCascade) {delete ioCascade; ioCascade=NULL;}
1042  delete vertexCasc; vertexCasc=NULL;
1043  } // end loop on soft pi tracks
1044 
1045  if(trackD0) {delete trackD0; trackD0=NULL;}
1046 
1047  }
1048  if(io2Prong) {delete io2Prong; io2Prong=NULL;}
1049  }
1050 
1051  twoTrackArray1->Clear();
1052  if( (!f3Prong && !f4Prong) ||
1053  (isLikeSign2Prong && !f3Prong) ) {
1054  negtrack1=0;
1055  delete vertexp1n1;
1056  continue;
1057  }
1058 
1059 
1060  // 2nd LOOP ON POSITIVE TRACKS
1061  for(iTrkP2=iTrkP1+1; iTrkP2<nSeleTrks; iTrkP2++) {
1062 
1063  if(iTrkP2==iTrkP1 || iTrkP2==iTrkN1) continue;
1064 
1065  //if(iTrkP2%1==0) AliDebug(1,Form(" 2nd loop on pos: track number %d of %d",iTrkP2,nSeleTrks));
1066 
1067  // get track from tracks array
1068  postrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkP2);
1069 
1070  if(postrack2->Charge()<0) continue;
1071 
1072  if(!TESTBIT(seleFlags[iTrkP2],kBitDispl)) continue;
1073 
1074  // Check single tracks cuts specific for 3 prongs
1075  if(!TESTBIT(seleFlags[iTrkP2],kBit3Prong)) continue;
1076  if(!TESTBIT(seleFlags[iTrkP1],kBit3Prong)) continue;
1077  if(!TESTBIT(seleFlags[iTrkN1],kBit3Prong)) continue;
1078 
1079  if(fMixEvent) {
1080  if(evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
1081  evtNumber[iTrkN1]==evtNumber[iTrkP2] ||
1082  evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
1083  }
1084 
1085  if(isLikeSign2Prong) { // like-sign pair -> have to build only like-sign triplet
1086  if(!fLikeSign3prong) continue;
1087  if(postrack1->Charge()>0) { // ok: like-sign triplet (+++)
1088  isLikeSign3Prong=kTRUE;
1089  } else { // not ok
1090  continue;
1091  }
1092  } else { // normal triplet (+-+)
1093  isLikeSign3Prong=kFALSE;
1094  if(fMixEvent) {
1095  if(evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
1096  evtNumber[iTrkN1]==evtNumber[iTrkP2] ||
1097  evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
1098  }
1099  }
1100 
1102  if(!TESTBIT(seleFlags[iTrkN1],kBitKaonCompat)) continue;
1103  }
1104  Bool_t okForLcTopKpi=kTRUE;
1105  Int_t pidLcStatus=3; // 3= OK as pKpi and Kpipi
1106  if(fUsePIDforLc>0){
1107  if(!TESTBIT(seleFlags[iTrkP1],kBitProtonCompat) &&
1108  !TESTBIT(seleFlags[iTrkP2],kBitProtonCompat) ){
1109  okForLcTopKpi=kFALSE;
1110  pidLcStatus=0;
1111  }
1112  if(okForLcTopKpi && fUsePIDforLc>1){
1113  okForLcTopKpi=kFALSE;
1114  pidLcStatus=0;
1115  if(TESTBIT(seleFlags[iTrkP1],kBitProtonCompat) &&
1116  TESTBIT(seleFlags[iTrkP2],kBitPionCompat) ){
1117  okForLcTopKpi=kTRUE;
1118  pidLcStatus+=1; // 1= OK as pKpi
1119  }
1120  if(TESTBIT(seleFlags[iTrkP2],kBitProtonCompat) &&
1121  TESTBIT(seleFlags[iTrkP1],kBitPionCompat) ){
1122  okForLcTopKpi=kTRUE;
1123  pidLcStatus+=2; // 2= OK as piKp
1124  }
1125  }
1126  }
1127  Bool_t okForDsToKKpi=kTRUE;
1128  if(fUseKaonPIDforDs){
1129  if(!TESTBIT(seleFlags[iTrkP1],kBitKaonCompat) &&
1130  !TESTBIT(seleFlags[iTrkP2],kBitKaonCompat) ) okForDsToKKpi=kFALSE;
1131  }
1132  // back to primary vertex
1133  // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1134  // postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1135  // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1136  SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1137  SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1138  SetParametersAtVertex(postrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP2));
1139 
1140  //printf("********** %d %d %d\n",postrack1->GetID(),postrack2->GetID(),negtrack1->GetID());
1141 
1142  dcap2n1 = postrack2->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
1143  if(dcap2n1>dcaMax) { postrack2=0; continue; }
1144  dcap1p2 = postrack2->GetDCA(postrack1,fBzkG,xdummy,ydummy);
1145  if(dcap1p2>dcaMax) { postrack2=0; continue; }
1146 
1147  // check invariant mass cuts for D+,Ds,Lc
1148  massCutOK=kTRUE;
1149  if(f3Prong) {
1150  if(postrack2->Charge()>0) {
1151  threeTrackArray->AddAt(postrack1,0);
1152  threeTrackArray->AddAt(negtrack1,1);
1153  threeTrackArray->AddAt(postrack2,2);
1154  } else {
1155  threeTrackArray->AddAt(negtrack1,0);
1156  threeTrackArray->AddAt(postrack1,1);
1157  threeTrackArray->AddAt(postrack2,2);
1158  }
1160  postrack2->GetPxPyPz(mompos2);
1161  Double_t pxDau[3]={mompos1[0],momneg1[0],mompos2[0]};
1162  Double_t pyDau[3]={mompos1[1],momneg1[1],mompos2[1]};
1163  Double_t pzDau[3]={mompos1[2],momneg1[2],mompos2[2]};
1164  // massCutOK = SelectInvMassAndPt3prong(threeTrackArray);
1165  massCutOK = SelectInvMassAndPt3prong(pxDau,pyDau,pzDau,pidLcStatus);
1166  }
1167  }
1168 
1169  if(f3Prong && !massCutOK) {
1170  threeTrackArray->Clear();
1171  if(!f4Prong) {
1172  postrack2=0;
1173  continue;
1174  }
1175  }
1176 
1177  // Vertexing
1178  twoTrackArray2->AddAt(postrack2,0);
1179  twoTrackArray2->AddAt(negtrack1,1);
1180 
1181  // 3 prong candidates
1182  if(f3Prong && massCutOK) {
1183 
1184  AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1185  io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,twoTrackArray2,dcap1n1,dcap2n1,dcap1p2,okForLcTopKpi,okForDsToKKpi,ok3Prong);
1186  if(ok3Prong) {
1187  AliAODVertex *v3Prong=0x0;
1188  if(!fMakeReducedRHF)v3Prong = new (verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
1189  if(!isLikeSign3Prong) {
1190  rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1191  // Set selection bit for PID
1195  if(fMakeReducedRHF){
1196  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1197  ((AliAODRecoDecayHF3Prong*)rd)->DeleteRecoD();
1198  }else{
1199  v3Prong = new (verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
1200  rd->SetSecondaryVtx(v3Prong);
1201  v3Prong->SetParent(rd);
1202  AddRefs(v3Prong,rd,event,threeTrackArray);
1203  }
1204  } else { // isLikeSign3Prong
1205  if(fLikeSign3prong){
1206  rd = new(aodLikeSign3ProngRef[iLikeSign3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1207  // Set selection bit for PID
1211  if(fMakeReducedRHF){
1212  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1213  ((AliAODRecoDecayHF3Prong*)rd)->DeleteRecoD();
1214  }else{
1215  rd->SetSecondaryVtx(v3Prong);
1216  v3Prong->SetParent(rd);
1217  AddRefs(v3Prong,rd,event,threeTrackArray);
1218  }
1219  }
1220  }
1221 
1222  }
1223  if(io3Prong) {delete io3Prong; io3Prong=NULL;}
1224  if(secVert3PrAOD) {delete secVert3PrAOD; secVert3PrAOD=NULL;}
1225  }
1226 
1227  // 4 prong candidates
1228  if(f4Prong
1229  // don't make 4 prong with like-sign pairs and triplets
1230  && !isLikeSign2Prong && !isLikeSign3Prong
1231  // track-to-track dca cuts already now
1232  && dcap1n1 < fCutsD0toKpipipi->GetDCACut()
1233  && dcap2n1 < fCutsD0toKpipipi->GetDCACut()) {
1234  // back to primary vertex
1235  // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1236  // postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1237  // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1238  SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1239  SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1240  SetParametersAtVertex(postrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP2));
1241 
1242  // Vertexing for these 3 (can be taken from above?)
1243  threeTrackArray->AddAt(postrack1,0);
1244  threeTrackArray->AddAt(negtrack1,1);
1245  threeTrackArray->AddAt(postrack2,2);
1246  AliAODVertex* vertexp1n1p2 = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1247 
1248  // 3rd LOOP ON NEGATIVE TRACKS (for 4 prong)
1249  for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
1250 
1251  if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
1252 
1253  //if(iTrkN2%1==0) AliDebug(1,Form(" 3rd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));
1254 
1255  // get track from tracks array
1256  negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
1257 
1258  if(negtrack2->Charge()>0) continue;
1259 
1260  if(!TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
1261  if(fMixEvent){
1262  if(evtNumber[iTrkP1]==evtNumber[iTrkN2] ||
1263  evtNumber[iTrkN1]==evtNumber[iTrkN2] ||
1264  evtNumber[iTrkP2]==evtNumber[iTrkN2] ||
1265  evtNumber[iTrkP1]==evtNumber[iTrkN1] ||
1266  evtNumber[iTrkP1]==evtNumber[iTrkP2] ||
1267  evtNumber[iTrkN1]==evtNumber[iTrkP2]) continue;
1268  }
1269 
1270  // back to primary vertex
1271  // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1272  // postrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1273  // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1274  // negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1275  SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1276  SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1277  SetParametersAtVertex(postrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP2));
1278  SetParametersAtVertex(negtrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN2));
1279 
1280  dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1281  if(dcap1n2 > fCutsD0toKpipipi->GetDCACut()) { negtrack2=0; continue; }
1282  dcap2n2 = postrack2->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1283  if(dcap2n2 > fCutsD0toKpipipi->GetDCACut()) { negtrack2=0; continue; }
1284 
1285 
1286  fourTrackArray->AddAt(postrack1,0);
1287  fourTrackArray->AddAt(negtrack1,1);
1288  fourTrackArray->AddAt(postrack2,2);
1289  fourTrackArray->AddAt(negtrack2,3);
1290 
1291  // check invariant mass cuts for D0
1292  massCutOK=kTRUE;
1294  massCutOK = SelectInvMassAndPt4prong(fourTrackArray);
1295 
1296  if(!massCutOK) {
1297  fourTrackArray->Clear();
1298  negtrack2=0;
1299  continue;
1300  }
1301 
1302  // Vertexing
1303  AliAODVertex* secVert4PrAOD = ReconstructSecondaryVertex(fourTrackArray,dispersion);
1304  io4Prong = Make4Prong(fourTrackArray,event,secVert4PrAOD,vertexp1n1,vertexp1n1p2,dcap1n1,dcap1n2,dcap2n1,dcap2n2,ok4Prong);
1305  if(ok4Prong) {
1306  rd = new(aodCharm4ProngRef[i4Prong++])AliAODRecoDecayHF4Prong(*io4Prong);
1307  if(fMakeReducedRHF){
1308  rd->DeleteRecoD();
1309  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1310  }else{
1311  AliAODVertex *v4Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert4PrAOD);
1312  rd->SetSecondaryVtx(v4Prong);
1313  v4Prong->SetParent(rd);
1314  AddRefs(v4Prong,rd,event,fourTrackArray);
1315  }
1316  }
1317 
1318  if(io4Prong) {delete io4Prong; io4Prong=NULL;}
1319  if(secVert4PrAOD) {delete secVert4PrAOD; secVert4PrAOD=NULL;}
1320  fourTrackArray->Clear();
1321  negtrack2 = 0;
1322 
1323  } // end loop on negative tracks
1324 
1325  threeTrackArray->Clear();
1326  delete vertexp1n1p2;
1327 
1328  }
1329 
1330  postrack2 = 0;
1331 
1332  } // end 2nd loop on positive tracks
1333 
1334  twoTrackArray2->Clear();
1335 
1336  // 2nd LOOP ON NEGATIVE TRACKS (for 3 prong -+-)
1337  for(iTrkN2=iTrkN1+1; iTrkN2<nSeleTrks; iTrkN2++) {
1338 
1339  if(iTrkN2==iTrkP1 || iTrkN2==iTrkP2 || iTrkN2==iTrkN1) continue;
1340 
1341  //if(iTrkN2%1==0) AliDebug(1,Form(" 2nd loop on neg: track number %d of %d",iTrkN2,nSeleTrks));
1342 
1343  // get track from tracks array
1344  negtrack2 = (AliESDtrack*)seleTrksArray.UncheckedAt(iTrkN2);
1345 
1346  if(negtrack2->Charge()>0) continue;
1347 
1348  if(!TESTBIT(seleFlags[iTrkN2],kBitDispl)) continue;
1349 
1350  // Check single tracks cuts specific for 3 prongs
1351  if(!TESTBIT(seleFlags[iTrkN2],kBit3Prong)) continue;
1352  if(!TESTBIT(seleFlags[iTrkP1],kBit3Prong)) continue;
1353  if(!TESTBIT(seleFlags[iTrkN1],kBit3Prong)) continue;
1354 
1355  if(fMixEvent) {
1356  if(evtNumber[iTrkP1]==evtNumber[iTrkN2] ||
1357  evtNumber[iTrkN1]==evtNumber[iTrkN2] ||
1358  evtNumber[iTrkP1]==evtNumber[iTrkN1]) continue;
1359  }
1360 
1361  if(isLikeSign2Prong) { // like-sign pair -> have to build only like-sign triplet
1362  if(!fLikeSign3prong) continue;
1363  if(postrack1->Charge()<0) { // ok: like-sign triplet (---)
1364  isLikeSign3Prong=kTRUE;
1365  } else { // not ok
1366  continue;
1367  }
1368  } else { // normal triplet (-+-)
1369  isLikeSign3Prong=kFALSE;
1370  }
1371 
1373  if(!TESTBIT(seleFlags[iTrkP1],kBitKaonCompat)) continue;
1374  }
1375  Bool_t okForLcTopKpi=kTRUE;
1376  Int_t pidLcStatus=3; // 3= OK as pKpi and Kpipi
1377  if(fUsePIDforLc>0){
1378  if(!TESTBIT(seleFlags[iTrkN1],kBitProtonCompat) &&
1379  !TESTBIT(seleFlags[iTrkN2],kBitProtonCompat) ){
1380  okForLcTopKpi=kFALSE;
1381  pidLcStatus=0;
1382  }
1383  if(okForLcTopKpi && fUsePIDforLc>1){
1384  okForLcTopKpi=kFALSE;
1385  pidLcStatus=0;
1386  if(TESTBIT(seleFlags[iTrkN1],kBitProtonCompat) &&
1387  TESTBIT(seleFlags[iTrkN2],kBitPionCompat) ){
1388  okForLcTopKpi=kTRUE;
1389  pidLcStatus+=1; // 1= OK as pKpi
1390  }
1391  if(TESTBIT(seleFlags[iTrkN2],kBitProtonCompat) &&
1392  TESTBIT(seleFlags[iTrkN1],kBitPionCompat) ){
1393  okForLcTopKpi=kTRUE;
1394  pidLcStatus+=2; // 2= OK as piKp
1395  }
1396  }
1397  }
1398  Bool_t okForDsToKKpi=kTRUE;
1399  if(fUseKaonPIDforDs){
1400  if(!TESTBIT(seleFlags[iTrkN1],kBitKaonCompat) &&
1401  !TESTBIT(seleFlags[iTrkN2],kBitKaonCompat) ) okForDsToKKpi=kFALSE;
1402  }
1403 
1404  // back to primary vertex
1405  // postrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1406  // negtrack1->PropagateToDCA(fV1,fBzkG,kVeryBig);
1407  // negtrack2->PropagateToDCA(fV1,fBzkG,kVeryBig);
1408  SetParametersAtVertex(postrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkP1));
1409  SetParametersAtVertex(negtrack1,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN1));
1410  SetParametersAtVertex(negtrack2,(AliExternalTrackParam*)tracksAtVertex.UncheckedAt(iTrkN2));
1411  //printf("********** %d %d %d\n",postrack1->GetID(),negtrack1->GetID(),negtrack2->GetID());
1412 
1413  dcap1n2 = postrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1414  if(dcap1n2>dcaMax) { negtrack2=0; continue; }
1415  dcan1n2 = negtrack1->GetDCA(negtrack2,fBzkG,xdummy,ydummy);
1416  if(dcan1n2>dcaMax) { negtrack2=0; continue; }
1417 
1418  threeTrackArray->AddAt(negtrack1,0);
1419  threeTrackArray->AddAt(postrack1,1);
1420  threeTrackArray->AddAt(negtrack2,2);
1421 
1422  // check invariant mass cuts for D+,Ds,Lc
1423  massCutOK=kTRUE;
1425  negtrack2->GetPxPyPz(momneg2);
1426  Double_t pxDau[3]={momneg1[0],mompos1[0],momneg2[0]};
1427  Double_t pyDau[3]={momneg1[1],mompos1[1],momneg2[1]};
1428  Double_t pzDau[3]={momneg1[2],mompos1[2],momneg2[2]};
1429  // massCutOK = SelectInvMassAndPt3prong(threeTrackArray);
1430  massCutOK = SelectInvMassAndPt3prong(pxDau,pyDau,pzDau,pidLcStatus);
1431  }
1432  if(!massCutOK) {
1433  threeTrackArray->Clear();
1434  negtrack2=0;
1435  continue;
1436  }
1437 
1438  // Vertexing
1439  twoTrackArray2->AddAt(postrack1,0);
1440  twoTrackArray2->AddAt(negtrack2,1);
1441 
1442  if(f3Prong) {
1443  AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray,dispersion);
1444  io3Prong = Make3Prong(threeTrackArray,event,secVert3PrAOD,dispersion,vertexp1n1,twoTrackArray2,dcap1n1,dcap1n2,dcan1n2,okForLcTopKpi,okForDsToKKpi,ok3Prong);
1445  if(ok3Prong) {
1446  AliAODVertex *v3Prong = 0x0;
1447  if(!fMakeReducedRHF) v3Prong = new(verticesHFRef[iVerticesHF++])AliAODVertex(*secVert3PrAOD);
1448  if(!isLikeSign3Prong) {
1449  rd = new(aodCharm3ProngRef[i3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1453  if(fMakeReducedRHF){
1454  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1455  ((AliAODRecoDecayHF3Prong*)rd)->DeleteRecoD();
1456  }else{
1457  rd->SetSecondaryVtx(v3Prong);
1458  v3Prong->SetParent(rd);
1459  AddRefs(v3Prong,rd,event,threeTrackArray);
1460  }
1461  } else { // isLikeSign3Prong
1462  if(fLikeSign3prong){
1463  rd = new(aodLikeSign3ProngRef[iLikeSign3Prong++])AliAODRecoDecayHF3Prong(*io3Prong);
1467  if(fMakeReducedRHF){
1468  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1469  ((AliAODRecoDecayHF3Prong*)rd)->DeleteRecoD();
1470  }else{
1471  rd->SetSecondaryVtx(v3Prong);
1472  v3Prong->SetParent(rd);
1473  AddRefs(v3Prong,rd,event,threeTrackArray);
1474  }
1475  }
1476 
1477  }
1478  }
1479  if(io3Prong) {delete io3Prong; io3Prong=NULL;}
1480  if(secVert3PrAOD) {delete secVert3PrAOD; secVert3PrAOD=NULL;}
1481  }
1482  threeTrackArray->Clear();
1483  negtrack2 = 0;
1484 
1485  } // end 2nd loop on negative tracks
1486 
1487  twoTrackArray2->Clear();
1488 
1489  negtrack1 = 0;
1490  delete vertexp1n1;
1491  } // end 1st loop on negative tracks
1492 
1493  postrack1 = 0;
1494  } // end 1st loop on positive tracks
1495 
1496 
1497  // AliDebug(1,Form(" Total HF vertices in event = %d;",
1498  // (Int_t)aodVerticesHFTClArr->GetEntriesFast()));
1499  if(fD0toKpi) {
1500  AliDebug(1,Form(" D0->Kpi in event = %d;",
1501  (Int_t)aodD0toKpiTClArr->GetEntriesFast()));
1502  }
1503  if(fJPSItoEle) {
1504  AliDebug(1,Form(" JPSI->ee in event = %d;",
1505  (Int_t)aodJPSItoEleTClArr->GetEntriesFast()));
1506  }
1507  if(f3Prong) {
1508  AliDebug(1,Form(" Charm->3Prong in event = %d;",
1509  (Int_t)aodCharm3ProngTClArr->GetEntriesFast()));
1510  }
1511  if(f4Prong) {
1512  AliDebug(1,Form(" Charm->4Prong in event = %d;\n",
1513  (Int_t)aodCharm4ProngTClArr->GetEntriesFast()));
1514  }
1515  if(fDstar) {
1516  AliDebug(1,Form(" D*->D0pi in event = %d;\n",
1517  (Int_t)aodDstarTClArr->GetEntriesFast()));
1518  }
1519  if(fCascades){
1520  AliDebug(1,Form(" cascades -> v0 + track in event = %d;\n",
1521  (Int_t)aodCascadesTClArr->GetEntriesFast()));
1522  }
1523  if(fLikeSign) {
1524  AliDebug(1,Form(" Like-sign 2Prong in event = %d;\n",
1525  (Int_t)aodLikeSign2ProngTClArr->GetEntriesFast()));
1526  }
1527  if(fLikeSign3prong && f3Prong) {
1528  AliDebug(1,Form(" Like-sign 3Prong in event = %d;\n",
1529  (Int_t)aodLikeSign3ProngTClArr->GetEntriesFast()));
1530  }
1531 
1532 
1533  twoTrackArray1->Delete(); delete twoTrackArray1;
1534  twoTrackArray2->Delete(); delete twoTrackArray2;
1535  twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
1536  twoTrackArrayV0->Delete(); delete twoTrackArrayV0;
1537  threeTrackArray->Clear();
1538  threeTrackArray->Delete(); delete threeTrackArray;
1539  fourTrackArray->Delete(); delete fourTrackArray;
1540  delete [] seleFlags; seleFlags=NULL;
1541  if(evtNumber) {delete [] evtNumber; evtNumber=NULL;}
1542  tracksAtVertex.Delete();
1543 
1544  if(fInputAOD) {
1545  seleTrksArray.Delete();
1546  if(fAODMap) { delete [] fAODMap; fAODMap=NULL; }
1547  }
1548 
1549 
1550  //printf("Trks: total %d sele %d\n",fnTrksTotal,fnSeleTrksTotal);
1551 
1552  return;
1553 }
1554 //----------------------------------------------------------------------------
1556  const AliVEvent *event,
1557  const TObjArray *trkArray) const
1558 {
1561  //AliCodeTimerAuto("",0);
1562 
1563  if(fInputAOD) {
1564  AddDaughterRefs(v,event,trkArray);
1565  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1566  }
1567 
1568  /*
1569  rd->SetListOfCutsRef((TList*)fListOfCuts);
1570  //fListOfCuts->Print();
1571  cout<<fListOfCuts<<endl;
1572  TList *l=(TList*)rd->GetListOfCuts();
1573  cout<<l<<endl;
1574  if(l) {l->Print(); }else{printf("error\n");}
1575  */
1576 
1577  return;
1578 }
1579 //---------------------------------------------------------------------------
1581  const AliVEvent *event,
1582  const TObjArray *trkArray) const
1583 {
1585  //AliCodeTimerAuto("",0);
1586 
1587  Int_t nDg = v->GetNDaughters();
1588  TObject *dg = 0;
1589  if(nDg) dg = v->GetDaughter(0);
1590 
1591  if(dg) return; // daughters already added
1592 
1593  Int_t nTrks = trkArray->GetEntriesFast();
1594 
1595  AliExternalTrackParam *track = 0;
1596  AliAODTrack *aodTrack = 0;
1597  Int_t id;
1598 
1599  for(Int_t i=0; i<nTrks; i++) {
1600  track = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
1601  id = (Int_t)track->GetID();
1602  //printf("---> %d\n",id);
1603  if(id<0) continue; // this track is a AliAODRecoDecay
1604  aodTrack = dynamic_cast<AliAODTrack*>(event->GetTrack(fAODMap[id]));
1605  if(!aodTrack) AliFatal("Not a standard AOD");
1606  v->AddDaughter(aodTrack);
1607  }
1608 
1609  return;
1610 }
1611 //----------------------------------------------------------------------------
1613 {
1616  //
1617  //AliCodeTimerAuto("",0);
1618 
1619 
1620  TClonesArray *inputArray=(TClonesArray*)aod->GetList()->FindObject("VerticesHF");
1621  if(!inputArray) return;
1622 
1623  AliAODTrack *track = 0;
1624  AliAODVertex *vertex = 0;
1625 
1626  Bool_t needtofix=kFALSE;
1627  for(Int_t iv=0; iv<inputArray->GetEntriesFast(); iv++) {
1628  vertex = (AliAODVertex*)inputArray->UncheckedAt(iv);
1629  for(Int_t id=0; id<vertex->GetNDaughters(); id++) {
1630  track = (AliAODTrack*)vertex->GetDaughter(id);
1631  if(!track->GetStatus()) needtofix=kTRUE;
1632  }
1633  if(needtofix) break;
1634  }
1635 
1636  if(!needtofix) return;
1637 
1638 
1639  printf("Fixing references\n");
1640 
1641  fAODMapSize = 100000;
1642  fAODMap = new Int_t[fAODMapSize];
1643  memset(fAODMap,0,sizeof(Int_t)*fAODMapSize);
1644 
1645  for(Int_t i=0; i<aod->GetNumberOfTracks(); i++) {
1646  track = dynamic_cast<AliAODTrack*>(aod->GetTrack(i));
1647  if(!track) AliFatal("Not a standard AOD");
1648 
1649  // skip pure ITS SA tracks
1650  if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
1651 
1652  // skip tracks without ITS
1653  if(!(track->GetStatus()&AliESDtrack::kITSin)) continue;
1654 
1655  // TEMPORARY: check that the cov matrix is there
1656  Double_t covtest[21];
1657  if(!track->GetCovarianceXYZPxPyPz(covtest)) continue;
1658  //
1659 
1660  Int_t ind = (Int_t)track->GetID();
1661  if (ind>-1 && ind < fAODMapSize) fAODMap[ind] = i;
1662  }
1663 
1664 
1665  Int_t ids[4]={-1,-1,-1,-1};
1666  for(Int_t iv=0; iv<inputArray->GetEntriesFast(); iv++) {
1667  Bool_t cascade=kFALSE;
1668  vertex = (AliAODVertex*)inputArray->UncheckedAt(iv);
1669  Int_t id=0;
1670  Int_t nDgs = vertex->GetNDaughters();
1671  for(id=0; id<nDgs; id++) {
1672  track = (AliAODTrack*)vertex->GetDaughter(id);
1673  if(track->Charge()==0) {cascade=kTRUE; continue;} // cascade
1674  ids[id]=(Int_t)track->GetID();
1675  vertex->RemoveDaughter(track);
1676  }
1677  if(cascade) continue;
1678  for(id=0; id<nDgs; id++) {
1679  if (ids[id]>-1 && ids[id] < fAODMapSize) {
1680  track = dynamic_cast<AliAODTrack*>(aod->GetTrack(fAODMap[ids[id]]));
1681  if(!track) AliFatal("Not a standard AOD");
1682  vertex->AddDaughter(track);
1683  }
1684  }
1685 
1686  }
1687 
1688  return;
1689 }
1690 
1691 //----------------------------------------------------------------------------
1692 AliAODTrack* AliAnalysisVertexingHF::GetProng(AliVEvent *event,AliAODRecoDecayHF *rd,Int_t iprong){
1693  if(!fAODMap)MapAODtracks(event);
1694  return (AliAODTrack*)event->GetTrack(fAODMap[rd->GetProngID(iprong)]);
1695 }
1696 
1697 //----------------------------------------------------------------------------
1699  // method to retrieve daughters from trackID and reconstruct secondary vertex
1700  // save the TRefs to the candidate AliAODRecoDecayHF3Prong rd
1701  // and fill on-the-fly the data member of rd
1702  if(rd->GetIsFilled()!=0)return kTRUE;//if 0: reduced dAOD. skip if rd is already filled (1: standard dAOD, 2 already refilled)
1703  if(!fAODMap)MapAODtracks(event);//fill the AOD index map if it is not yet done
1704  TObjArray *threeTrackArray = new TObjArray(3);
1705 
1706  AliAODTrack *track1 =(AliAODTrack*)event->GetTrack(fAODMap[rd->GetProngID(0)]);//retrieve daughter from the trackID through the AOD index map
1707  if(!track1)return kFALSE;
1708  AliAODTrack *track2 =(AliAODTrack*)event->GetTrack(fAODMap[rd->GetProngID(1)]);
1709  if(!track2)return kFALSE;
1710  AliESDtrack *postrack1 = 0;
1711  AliESDtrack *negtrack1 = 0;
1712  postrack1 = new AliESDtrack(track1);
1713  negtrack1 = new AliESDtrack(track2);
1714 
1715  // DCA between the two tracks
1716  Double_t xdummy, ydummy;
1717  fBzkG = (Double_t)event->GetMagneticField();
1718  Double_t dca12 = postrack1->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
1719 
1720  const AliVVertex *vprimary = event->GetPrimaryVertex();
1721  Double_t pos[3];
1722  Double_t cov[6];
1723  vprimary->GetXYZ(pos);
1724  vprimary->GetCovarianceMatrix(cov);
1725  fV1 = new AliESDVertex(pos,cov,100.,100,vprimary->GetName());
1726  fV1->GetCovMatrix(cov);
1727  if(!fVertexerTracks)fVertexerTracks=new AliVertexerTracks(fBzkG);
1728 
1729  AliAODTrack *track3 =(AliAODTrack*)event->GetTrack(fAODMap[rd->GetProngID(2)]);
1730  if(!track3)return kFALSE;
1731  AliESDtrack *esdt3 = new AliESDtrack(track3);
1732 
1733  Double_t dca2;
1734  Double_t dca3;
1735  threeTrackArray->AddAt(postrack1,0);
1736  threeTrackArray->AddAt(negtrack1,1);
1737  threeTrackArray->AddAt(esdt3,2);
1738  dca2 = esdt3->GetDCA(negtrack1,fBzkG,xdummy,ydummy);
1739  dca3 = esdt3->GetDCA(postrack1,fBzkG,xdummy,ydummy);
1740  Double_t dispersion;
1741 
1742  AliAODVertex* secVert3PrAOD = ReconstructSecondaryVertex(threeTrackArray, dispersion);
1743  if (!secVert3PrAOD) {
1744  threeTrackArray->Clear();
1745  threeTrackArray->Delete(); delete threeTrackArray;
1746  delete fV1; fV1=0;
1747  delete postrack1; postrack1=NULL;
1748  delete negtrack1; negtrack1=NULL;
1749  delete esdt3; esdt3=NULL;
1750  return kFALSE;
1751  }
1752 
1753  rd->SetNProngs();
1754  Double_t vtxRec=rd->GetDist12toPrim();
1755  Double_t vertexp2n1=rd->GetDist23toPrim();
1756  rd= Make3Prong(threeTrackArray, event, secVert3PrAOD,dispersion, vtxRec, vertexp2n1, dca12, dca2, dca3, rd);
1757  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1758  rd->SetIsFilled(2);
1759  threeTrackArray->Clear();
1760  threeTrackArray->Delete(); delete threeTrackArray;
1761  delete fV1; fV1=0;
1762  delete postrack1; postrack1=NULL;
1763  delete negtrack1; negtrack1=NULL;
1764  delete esdt3; esdt3=NULL;
1765  return kTRUE;
1766 }
1767 //___________________________
1769  // method to retrieve daughters from trackID and reconstruct secondary vertex
1770  // save the TRefs to the candidate AliAODRecoDecayHF2Prong rd
1771  // and fill on-the-fly the data member of rd
1772  if(rd->GetIsFilled()!=0)return kTRUE;//if 0: reduced dAOD. skip if rd is already filled (1:standard dAOD, 2 already refilled)
1773  if(!fAODMap)MapAODtracks(event);//fill the AOD index map if it is not yet done
1774 
1775  Double_t dispersion;
1776  TObjArray *twoTrackArray1 = new TObjArray(2);
1777 
1778  AliAODTrack *track1 =(AliAODTrack*)event->GetTrack(fAODMap[rd->GetProngID(0)]);//retrieve daughter from the trackID through the AOD index map
1779  if(!track1)return kFALSE;
1780  AliAODTrack *track2 =(AliAODTrack*)event->GetTrack(fAODMap[rd->GetProngID(1)]);
1781  if(!track2)return kFALSE;
1782 
1783  AliESDtrack *esdt1 = 0;
1784  AliESDtrack *esdt2 = 0;
1785  esdt1 = new AliESDtrack(track1);
1786  esdt2 = new AliESDtrack(track2);
1787 
1788  twoTrackArray1->AddAt(esdt1,0);
1789  twoTrackArray1->AddAt(esdt2,1);
1790  // DCA between the two tracks
1791  Double_t xdummy, ydummy;
1792  fBzkG = (Double_t)event->GetMagneticField();
1793  Double_t dca12 = esdt1->GetDCA(esdt2,fBzkG,xdummy,ydummy);
1794  const AliVVertex *vprimary = event->GetPrimaryVertex();
1795  Double_t pos[3];
1796  Double_t cov[6];
1797  vprimary->GetXYZ(pos);
1798  vprimary->GetCovarianceMatrix(cov);
1799  fV1 = new AliESDVertex(pos,cov,100.,100,vprimary->GetName());
1800  fV1->GetCovMatrix(cov);
1801  if(!fVertexerTracks)fVertexerTracks=new AliVertexerTracks(fBzkG);
1802 
1803 
1804  AliAODVertex *vtxRec = ReconstructSecondaryVertex(twoTrackArray1, dispersion);
1805  if(!vtxRec) {
1806  twoTrackArray1->Clear();
1807  twoTrackArray1->Delete(); delete twoTrackArray1;
1808  delete fV1; fV1=0;
1809  delete esdt1; esdt1=NULL;
1810  delete esdt2; esdt2=NULL;
1811  return kFALSE; }
1812  Bool_t okD0=kFALSE;
1813  Bool_t okJPSI=kFALSE;
1814  Bool_t okD0FromDstar=kFALSE;
1815  Bool_t refill =kTRUE;
1816  rd->SetNProngs();
1817  rd= Make2Prong(twoTrackArray1, event, vtxRec, dca12, okD0, okJPSI, okD0FromDstar, kFALSE, refill, rd);
1818  rd->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1819  rd->SetIsFilled(2);
1820  delete fV1; fV1=0;
1821  twoTrackArray1->Clear();
1822  twoTrackArray1->Delete(); delete twoTrackArray1;
1823  delete esdt1; esdt1=NULL;
1824  delete esdt2; esdt2=NULL;
1825  return kTRUE;
1826 }
1827 //----------------------------------------------------------------------------
1829  // method to retrieve daughters from trackID
1830  // and fill on-the-fly the data member of rCasc and their AliAODRecoDecayHF2Prong daughters
1831  if(rCasc->GetIsFilled()!=0) return kTRUE;//if 0: reduced dAOD. skip if rd is already filled (1: standard dAOD, 2: already refilled)
1832  if(!fAODMap)MapAODtracks(event);//fill the AOD index map if it is not yet done
1833  TObjArray *twoTrackArrayCasc = new TObjArray(2);
1834 
1835  AliAODTrack *trackB =(AliAODTrack*)event->GetTrack(fAODMap[rCasc->GetProngID(0)]);//retrieve bachelor from the trackID through the AOD index map
1836  if(!trackB)return kFALSE;
1837 
1838  AliNeutralTrackParam *trackV0=NULL;
1839  AliAODv0 *v0 =NULL;
1840  AliAODRecoDecayHF2Prong *trackD0=NULL;
1841  rCasc->SetNProngs();
1842 
1843  if(DStar){
1844  TClonesArray *inputArrayD0=(TClonesArray*)event->GetList()->FindObject("D0toKpi");
1845  if(!inputArrayD0) return kFALSE;
1846  trackD0=(AliAODRecoDecayHF2Prong*)inputArrayD0->At(rCasc->GetProngID(1));
1847  if(!trackD0)return kFALSE;
1848  if(!FillRecoCand(event,trackD0)) return kFALSE; //fill missing info of the corresponding D0 daughter
1849 
1850  trackV0 = new AliNeutralTrackParam(trackD0);
1851 
1852  }else{//is a V0 candidate
1853  v0 = ((AliAODEvent*)event)->GetV0(rCasc->GetProngID(1));
1854  if(!v0) return kFALSE;
1855  // Define the V0 (neutral) track
1856  const AliVTrack *trackVV0 = dynamic_cast<const AliVTrack*>(v0);
1857  if(trackVV0) trackV0 = new AliNeutralTrackParam(trackVV0);
1858  }
1859 
1860  AliESDtrack *esdB = new AliESDtrack(trackB);
1861 
1862  twoTrackArrayCasc->AddAt(esdB,0);
1863  twoTrackArrayCasc->AddAt(trackV0,1);
1864 
1865  fBzkG = (Double_t)event->GetMagneticField();
1866  const AliVVertex *vprimary = event->GetPrimaryVertex();
1867 
1868  Double_t pos[3];
1869  Double_t cov[6];
1870  vprimary->GetXYZ(pos);
1871  vprimary->GetCovarianceMatrix(cov);
1872  fV1 = new AliESDVertex(pos,cov,100.,100,vprimary->GetName());
1873  fV1->GetCovMatrix(cov);
1874 
1875  Double_t dca = 0.;
1876  AliAODVertex *vtxCasc = 0x0;
1877  Double_t chi2perNDF = fV1->GetChi2toNDF();
1878  if (recoSecVtx) {
1879  Double_t dispersion, xdummy, ydummy;
1880  dca = esdB->GetDCA(trackV0,fBzkG,xdummy,ydummy);
1881  if (!fVertexerTracks) fVertexerTracks = new AliVertexerTracks(fBzkG);
1882  vtxCasc = ReconstructSecondaryVertex(twoTrackArrayCasc,dispersion,kFALSE);
1883  } else {
1884  vtxCasc = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,2);
1885  }
1886  if(!vtxCasc) {
1887  twoTrackArrayCasc->Clear();
1888  twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
1889  delete fV1; fV1=0;
1890  delete esdB; esdB=NULL;
1891  delete vtxCasc;vtxCasc=NULL;
1892  trackB=NULL;
1893  delete trackV0; trackV0=NULL;
1894  if(!DStar){
1895  v0=NULL;
1896  }
1897  return kFALSE;
1898  }
1899  vtxCasc->SetParent(rCasc);
1900  rCasc->SetSecondaryVtx(vtxCasc);
1901  AddDaughterRefs(vtxCasc,(AliAODEvent*)event,twoTrackArrayCasc);
1902  if(DStar)vtxCasc->AddDaughter(trackD0);
1903  else vtxCasc->AddDaughter(v0);
1904  rCasc->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
1905 
1906  Double_t px[2],py[2],pz[2],d0[2],d0err[2];
1907  // propagate tracks to secondary vertex, to compute inv. mass
1908  esdB->PropagateToDCA(vtxCasc,fBzkG,kVeryBig);
1909  trackV0->PropagateToDCA(vtxCasc,fBzkG,kVeryBig);
1910  Double_t momentum[3];
1911  esdB->GetPxPyPz(momentum);
1912  px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
1913  trackV0->GetPxPyPz(momentum);
1914  px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
1915 
1916  AliAODVertex *primVertexAOD = PrimaryVertex(twoTrackArrayCasc,event);
1917  if(!primVertexAOD){
1918  delete fV1; fV1=0;
1919  delete vtxCasc; vtxCasc=NULL;
1920  twoTrackArrayCasc->Clear();
1921  twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
1922  delete esdB; esdB=NULL;
1923  delete trackV0; trackV0=NULL;
1924  if(!DStar)v0=NULL;
1925  return kFALSE;
1926  }
1927  Double_t d0z0[2],covd0z0[3];
1928  esdB->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1929  d0[0] = d0z0[0];
1930  d0err[0] = TMath::Sqrt(covd0z0[0]);
1931  trackV0->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
1932  d0[1] = d0z0[0];
1933  d0err[1] = TMath::Sqrt(covd0z0[0]);
1934  rCasc->SetPxPyPzProngs(2,px,py,pz);
1935  rCasc->SetDCA(dca);
1936  rCasc->Setd0Prongs(2,d0);
1937  rCasc->Setd0errProngs(2,d0err);
1938  rCasc->SetOwnPrimaryVtx(primVertexAOD);
1939  rCasc->SetCharge(esdB->Charge());
1940  // get PID info from ESD
1941  Double_t esdpid0[5]={0.,0.,0.,0.,0.};
1942  if(esdB->GetStatus()&AliESDtrack::kESDpid) esdB->GetESDpid(esdpid0);
1943  Double_t esdpid1[5]={0.,0.,0.,0.,0.};
1944  Double_t esdpid[10];
1945  for(Int_t i=0;i<5;i++) {
1946  esdpid[i] = esdpid0[i];
1947  esdpid[5+i] = esdpid1[i];
1948  }
1949  rCasc->SetPID(2,esdpid);
1950  rCasc->SetIsFilled(2);
1951 
1952 
1953  delete fV1; fV1=0;
1954  if(primVertexAOD) {delete primVertexAOD; primVertexAOD=NULL;}
1955  twoTrackArrayCasc->Clear();
1956  twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
1957  delete esdB; esdB=NULL;
1958  delete trackV0; trackV0=NULL;
1959  if(!DStar)v0=NULL;
1960  return kTRUE;
1961 }
1962 //---------------------------------------------------------------------------
1964 {
1969 
1970 
1971  if (rc->GetIsFilled()==0) return kFALSE; // Reduced dAOD with candidates not yet refilled
1972  if (!fAODMap) MapAODtracks(event); // Fill the AOD index map if it is not yet done
1973 
1974 
1975  // - Get bachelor and V0 from the cascade
1976  AliAODTrack *trackB = dynamic_cast<AliAODTrack*> (rc->GetBachelor());
1977  if (!trackB) return kFALSE;
1978 
1979  AliAODv0 *v0 = dynamic_cast<AliAODv0*> (rc->Getv0());
1980  if (!v0) return kFALSE;
1981 
1982 
1983  // - Cast bachelor (AOD->ESD) and V0 (AliAODv0->AliNeutralTrackParam)
1984  AliESDtrack *esdB = new AliESDtrack(trackB);
1985  if (!esdB) return kFALSE;
1986 
1987  const AliVTrack *trackVV0 = dynamic_cast<const AliVTrack*>(v0);
1988  if (!trackVV0) return kFALSE;
1989 
1990  AliNeutralTrackParam *trackV0 = new AliNeutralTrackParam(trackVV0);
1991  if (!trackV0) return kFALSE;
1992 
1993  TObjArray *twoTrackArrayCasc = new TObjArray(2);
1994  twoTrackArrayCasc->AddAt(esdB, 0);
1995  twoTrackArrayCasc->AddAt(trackV0, 1);
1996 
1997 
1998  Double_t dispersion, xdummy, ydummy, pos[3], cov[6];
1999 
2000 
2001  // - Some ingredients will be needed:
2002  // magnetic field
2003  fBzkG = (Double_t) event->GetMagneticField();
2004 
2005  // primary vertex
2006  const AliVVertex *vprimary = event->GetPrimaryVertex();
2007  vprimary->GetXYZ(pos);
2008  vprimary->GetCovarianceMatrix(cov);
2009  fV1 = new AliESDVertex(pos,cov,100.,100,vprimary->GetName());
2010 
2011  // vertexer
2012  if (!fVertexerTracks) fVertexerTracks = new AliVertexerTracks(fBzkG);
2013 
2014 
2015  // - Compute the DCA and the decay vertex
2016  Double_t dca = esdB->GetDCA(trackV0, fBzkG, xdummy, ydummy);
2017  AliAODVertex *vtxCasc = ReconstructSecondaryVertex(twoTrackArrayCasc, dispersion, kFALSE);
2018 
2019  if (!vtxCasc) {
2020  twoTrackArrayCasc->Clear();
2021  twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
2022  delete fV1; fV1=0;
2023  delete esdB; esdB=0;
2024  delete vtxCasc; vtxCasc=0;
2025  delete trackV0; trackV0=0;
2026  trackB=0; v0=0;
2027  return kFALSE;
2028  }
2029 
2030 
2031  // - Linking the cascade with the new secondary vertex
2032  vtxCasc->SetParent(rc);
2033  rc->SetSecondaryVtx(vtxCasc);
2034  AddDaughterRefs(vtxCasc, (AliAODEvent*)event, twoTrackArrayCasc);
2035  vtxCasc->AddDaughter(v0);
2036  rc->SetPrimaryVtxRef((AliAODVertex*)event->GetPrimaryVertex());
2037 
2038 
2039  // - Propagate tracks to secondary vertex, to get momenta
2040  Double_t momentum[3], px[2], py[2], pz[2], d0[2], d0err[2], d0z0[2], covd0z0[3];
2041  esdB->PropagateToDCA(vtxCasc, fBzkG, kVeryBig);
2042  trackV0->PropagateToDCA(vtxCasc, fBzkG, kVeryBig);
2043  esdB->GetPxPyPz(momentum);
2044  px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
2045  trackV0->GetPxPyPz(momentum);
2046  px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
2047 
2048 
2049  // - Propagate tracks to primary vertex, to get impact parameters
2050  AliAODVertex *primVertexAOD = PrimaryVertex(twoTrackArrayCasc, event);
2051  if (!primVertexAOD) {
2052  twoTrackArrayCasc->Clear();
2053  twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
2054  delete fV1; fV1=0;
2055  delete esdB; esdB=0;
2056  delete vtxCasc; vtxCasc=0;
2057  delete trackV0; trackV0=0;
2058  trackB=0; v0=0;
2059  return kFALSE;
2060  }
2061 
2062  esdB->PropagateToDCA(primVertexAOD, fBzkG, kVeryBig, d0z0, covd0z0);
2063  d0[0] = d0z0[0];
2064  d0err[0] = TMath::Sqrt(covd0z0[0]);
2065  trackV0->PropagateToDCA(primVertexAOD, fBzkG, kVeryBig, d0z0, covd0z0);
2066  d0[1] = d0z0[0];
2067  d0err[1] = TMath::Sqrt(covd0z0[0]);
2068 
2069 
2070  // - Get PID info from ESD
2071  Double_t esdpid[10];
2072  Double_t esdpid0[5] = {0., 0., 0., 0., 0.};
2073  Double_t esdpid1[5] = {0., 0., 0., 0., 0.};
2074  if (esdB->GetStatus()&AliESDtrack::kESDpid) esdB->GetESDpid(esdpid0);
2075  for (Int_t ipid=0; ipid<5; ipid++) {
2076  esdpid[ipid] = esdpid0[ipid];
2077  esdpid[5+ipid] = esdpid1[ipid];
2078  }
2079 
2080 
2081  // - Set data members
2082  rc->SetOwnPrimaryVtx(primVertexAOD);
2083  rc->SetDCA(dca);
2084  rc->SetPxPyPzProngs(2, px, py, pz);
2085  rc->Setd0Prongs(2, d0);
2086  rc->Setd0errProngs(2, d0err);
2087  rc->SetCharge(esdB->Charge());
2088  rc->SetPID(2, esdpid);
2089 
2090  rc->SetIsFilled(2); // To clean the newly reconstructed secondary vertex with the CleanUp task
2091 
2092 
2093  twoTrackArrayCasc->Clear();
2094  twoTrackArrayCasc->Delete(); delete twoTrackArrayCasc;
2095  delete fV1; fV1=0;
2096  delete primVertexAOD; primVertexAOD=0;
2097  delete esdB; esdB=0;
2098  delete trackV0; trackV0=0;
2099  trackB=0; v0=0;
2100 
2101  return kTRUE;
2102 }
2103 
2104 //---------------------------------------------------------------------------
2106  TObjArray *twoTrackArray,AliVEvent *event,
2107  AliAODVertex *secVert,
2108  AliAODRecoDecayHF2Prong *rd2Prong,
2109  Double_t dca,
2110  Bool_t &okDstar)
2111 {
2114  //AliCodeTimerAuto("",0);
2115  UInt_t ntref=TProcessID::GetObjectCount();
2116  if(ntref>16776216){// This number is 2^24-1000. The maximum number of TRef for a given TProcesssID is 2^24=16777216.
2117  AliFatal(Form("Number of TRef created (=%d), close to limit (16777216)",ntref));
2118  }
2119 
2120  okDstar = kFALSE;
2121 
2122  Bool_t dummy1,dummy2,dummy3;
2123 
2124  // We use Make2Prong to construct the AliAODRecoCascadeHF
2125  // (which inherits from AliAODRecoDecayHF2Prong)
2126  AliAODRecoCascadeHF *theCascade =
2127  (AliAODRecoCascadeHF*)Make2Prong(twoTrackArray,event,secVert,dca,
2128  dummy1,dummy2,dummy3);
2129  if(!theCascade) return 0x0;
2130 
2131  // charge
2132  AliESDtrack *trackPi = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
2133  theCascade->SetCharge(trackPi->Charge());
2134 
2135  //--- selection cuts
2136  //
2137  AliAODRecoCascadeHF *tmpCascade = new AliAODRecoCascadeHF(*theCascade);
2138  if(fInputAOD){
2139  Int_t idSoftPi=(Int_t)trackPi->GetID();
2140  if (idSoftPi > -1 && idSoftPi < fAODMapSize) {
2141  AliAODTrack* trackPiAOD=dynamic_cast<AliAODTrack*>(event->GetTrack(fAODMap[idSoftPi]));
2142  if(!trackPiAOD) AliFatal("Not a standard AOD");
2143  tmpCascade->GetSecondaryVtx()->AddDaughter(trackPiAOD);
2144  }
2145  }else{
2146  tmpCascade->GetSecondaryVtx()->AddDaughter(trackPi);
2147  }
2148  tmpCascade->GetSecondaryVtx()->AddDaughter(rd2Prong);
2149 
2150  AliAODVertex *primVertexAOD=0;
2152  // take event primary vertex
2153  primVertexAOD = PrimaryVertex();
2154  tmpCascade->SetOwnPrimaryVtx(primVertexAOD);
2155  rd2Prong->SetOwnPrimaryVtx(primVertexAOD);
2156  }
2157  // select D*->D0pi
2158  if(fDstar) {
2160  if(okDstar) theCascade->SetSelectionBit(AliRDHFCuts::kDstarCuts);
2161  }
2162  tmpCascade->GetSecondaryVtx()->RemoveDaughters();
2163  tmpCascade->UnsetOwnPrimaryVtx();
2164  delete tmpCascade; tmpCascade=NULL;
2166  rd2Prong->UnsetOwnPrimaryVtx();
2167  }
2168  if(primVertexAOD) {delete primVertexAOD; primVertexAOD=NULL;}
2169  //---
2170 
2171 
2172  return theCascade;
2173 }
2174 
2175 
2176 //----------------------------------------------------------------------------
2178  TObjArray *twoTrackArray,AliVEvent *event,
2179  AliAODVertex *secVert,
2180  AliAODv0 *v0,
2181  Double_t dca,
2182  Bool_t &okCascades)
2183 {
2186  //AliCodeTimerAuto("",0);
2187  UInt_t ntref=TProcessID::GetObjectCount();
2188  if(ntref>16776216){// This number is 2^24-1000. The maximum number of TRef for a given TProcesssID is 2^24=16777216.
2189  AliFatal(Form("Number of TRef created (=%d), close to limit (16777216)",ntref));
2190  }
2191 
2192  // preselection to reduce the number of TRefs
2193  Double_t px[2],py[2],pz[2];
2194  AliESDtrack *postrack = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
2195  AliESDtrack *negtrack = (AliESDtrack*)twoTrackArray->UncheckedAt(1);
2196  Double_t momentum[3];
2197  GetTrackMomentumAtSecVert(postrack,secVert,momentum);
2198  px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
2199  GetTrackMomentumAtSecVert(negtrack,secVert,momentum);
2200  px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
2201 
2202  if(!fMassCutBeforeVertexing && !SelectInvMassAndPtCascade(px,py,pz)) return 0x0;
2203  Double_t dummyd0[2]={0,0};
2204  Double_t dummyd0err[2]={0,0};
2205  AliAODRecoCascadeHF tmpCasc(0x0,postrack->Charge(),px, py, pz, dummyd0, dummyd0err,0.);
2206  // pre-selection with cuts not requiring the full AOD cascade object
2207  Bool_t presel=kFALSE;
2208  if(fCutsLctoV0->PreSelect(&tmpCasc,v0,postrack)) presel=kTRUE;
2209  if(!presel && fCutsDplustoK0spi){
2210  if(fCutsDplustoK0spi->PreSelect(&tmpCasc,v0,postrack)) presel=kTRUE;
2211  }
2212  if(!presel && fCutsDstoK0sK){
2213  if(fCutsDplustoK0spi->PreSelect(&tmpCasc,v0,postrack)) presel=kTRUE;
2214  }
2215  if(!presel) return 0x0;
2216 
2217  // AliDebug(2,Form(" building the cascade"));
2218  okCascades = kFALSE;
2219  Bool_t dummy1,dummy2,dummy3;
2220 
2221  // We use Make2Prong to construct the AliAODRecoCascadeHF
2222  // (which inherits from AliAODRecoDecayHF2Prong)
2223  AliAODRecoCascadeHF *theCascade =
2224  (AliAODRecoCascadeHF*)Make2Prong(twoTrackArray,event,secVert,dca,
2225  dummy1,dummy2,dummy3,kTRUE);
2226  if(!theCascade) return 0x0;
2227 
2228  // bachelor track and charge
2229  AliESDtrack *trackBachelor = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
2230  theCascade->SetCharge(trackBachelor->Charge());
2231 
2232  // Add daughters
2233  if(fInputAOD){
2234  Int_t idBachelor=(Int_t)trackBachelor->GetID();
2235  if (idBachelor > -1 && idBachelor < fAODMapSize) {
2236  AliAODTrack* trackBachelorAOD=dynamic_cast<AliAODTrack*>(event->GetTrack(fAODMap[idBachelor]));
2237  if(!trackBachelorAOD) AliFatal("Not a standard AOD");
2238  theCascade->GetSecondaryVtx()->AddDaughter(trackBachelorAOD);
2239  }
2240  }else{
2241  theCascade->GetSecondaryVtx()->AddDaughter(trackBachelor);
2242  }
2243  theCascade->GetSecondaryVtx()->AddDaughter(v0);
2244 
2245  // select Cascades
2246  if (fCascades && fInputAOD) {
2247  if (fCutsLctoV0->IsSelected(theCascade, AliRDHFCuts::kCandidate)>0) {
2248  okCascades = kTRUE;
2250  }
2251  if (fCutsDplustoK0spi) {
2253  okCascades = kTRUE;
2255  }
2256  }
2257  if (fCutsDstoK0sK){
2258  if (fCutsDstoK0sK->IsSelected(theCascade, AliRDHFCuts::kCandidate)>0) {
2259  okCascades = kTRUE;
2261  }
2262  }
2263  }
2264  else {
2265  //AliDebug(2,Form("The cascade is contructed from ESDs, no cuts are applied"));
2266  okCascades=kTRUE;
2270  } // no cuts implemented from ESDs
2271  theCascade->GetSecondaryVtx()->RemoveDaughters();
2272  theCascade->UnsetOwnPrimaryVtx();
2273 
2274  return theCascade;
2275 }
2276 
2277 //-----------------------------------------------------------------------------
2279  TObjArray *twoTrackArray,AliVEvent *event,
2280  AliAODVertex *secVert,Double_t dca,
2281  Bool_t &okD0,Bool_t &okJPSI,
2282  Bool_t &okD0fromDstar, Bool_t callFromCascade,
2283  Bool_t refill, AliAODRecoDecayHF2Prong *rd)
2284 {
2287  // G.E.Bruno (J/psi), A.Dainese (D0->Kpi)
2288  // AliCodeTimerAuto("",0);
2289  okD0=kFALSE; okJPSI=kFALSE; okD0fromDstar=kFALSE;
2290 
2291  UInt_t ntref=TProcessID::GetObjectCount();
2292  if(ntref>16776216){// This number is 2^24-1000. The maximum number of TRef for a given TProcesssID is 2^24=16777216.
2293  AliFatal(Form("Number of TRef created (=%d), close to limit (16777216)",ntref));
2294  }
2295 
2296  Double_t px[2],py[2],pz[2],d0[2],d0err[2];
2297  AliESDtrack *postrack = (AliESDtrack*)twoTrackArray->UncheckedAt(0);
2298  AliESDtrack *negtrack = (AliESDtrack*)twoTrackArray->UncheckedAt(1);
2299 
2300  Double_t momentum[3];
2301  GetTrackMomentumAtSecVert(postrack,secVert,momentum);
2302  px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
2303  GetTrackMomentumAtSecVert(negtrack,secVert,momentum);
2304  px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
2305 
2306  if(!refill && !callFromCascade){
2307  //skip if it is called in refill step or for V0+bachelor because already checked
2308  Bool_t okMassCut=kFALSE;
2309  if(!okMassCut && fD0toKpi) if(SelectInvMassAndPtD0Kpi(px,py,pz)) okMassCut=kTRUE;
2310  if(!okMassCut && fJPSItoEle) if(SelectInvMassAndPtJpsiee(px,py,pz)) okMassCut=kTRUE;
2311  if(!okMassCut && fDstar) if(SelectInvMassAndPtDstarD0pi(px,py,pz)) okMassCut=kTRUE;
2312  if(!okMassCut) {
2313  //AliDebug(2," candidate didn't pass mass cut");
2314  return 0x0;
2315  }
2316  }
2317  // primary vertex to be used by this candidate
2318  AliAODVertex *primVertexAOD = 0x0;
2319  Float_t d0z0f[2],covd0z0f[3];
2320  if(!refill && !fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) {
2321  postrack->GetImpactParameters(d0z0f,covd0z0f);
2322  d0[0]=d0z0f[0];
2323  d0err[0] = TMath::Sqrt(covd0z0f[0]);
2324  negtrack->GetImpactParameters(d0z0f,covd0z0f);
2325  d0[1]=d0z0f[0];
2326  d0err[1] = TMath::Sqrt(covd0z0f[0]);
2327  }else{
2328  primVertexAOD = PrimaryVertex(twoTrackArray,event);
2329  if(!primVertexAOD) return 0x0;
2330  Double_t d0z0[2],covd0z0[3];
2331  // do not prapagate neutral tracks, which are there for D* and V0+bachelor candidates
2332  if(postrack->Charge()!=0){
2333  postrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2334  d0[0] = d0z0[0];
2335  d0err[0] = TMath::Sqrt(covd0z0[0]);
2336  }else{
2337  postrack->GetImpactParameters(d0z0f,covd0z0f);
2338  d0[0]=d0z0f[0];
2339  d0err[0] = TMath::Sqrt(covd0z0f[0]);
2340  }
2341  if(negtrack->Charge()!=0){
2342  negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2343  d0[1] = d0z0[0];
2344  d0err[1] = TMath::Sqrt(covd0z0[0]);
2345  }else{
2346  negtrack->GetImpactParameters(d0z0f,covd0z0f);
2347  d0[1]=d0z0f[0];
2348  d0err[1] = TMath::Sqrt(covd0z0f[0]);
2349  }
2350  }
2351 
2352  AliAODRecoDecayHF2Prong *the2Prong;
2353  // create the object AliAODRecoDecayHF2Prong
2354  if(!refill){
2355  the2Prong = new AliAODRecoDecayHF2Prong(secVert,px,py,pz,d0,d0err,dca);
2356  if(primVertexAOD) the2Prong->SetOwnPrimaryVtx(primVertexAOD);
2357  else the2Prong->SetOwnPrimaryVtx(fV1AOD);
2358  UShort_t id[2]={(UShort_t)postrack->GetID(),(UShort_t)negtrack->GetID()};
2359  the2Prong->SetProngIDs(2,id);
2360  if(postrack->Charge()!=0 && negtrack->Charge()!=0) { // don't apply these cuts if it's a D* or a V0+bachelor
2361  // Add daughter references already here
2362  if(fInputAOD) AddDaughterRefs(secVert,(AliAODEvent*)event,twoTrackArray);
2363 
2364  // select D0->Kpi
2365  if(fD0toKpi) {
2367  if(okD0) the2Prong->SetSelectionBit(AliRDHFCuts::kD0toKpiCuts);
2368  }
2369  //if(fDebug && fD0toKpi) printf(" %d\n",(Int_t)okD0);
2370  // select J/psi from B
2371  if(fJPSItoEle) {
2373  }
2374  //if(fDebug && fJPSItoEle) printf(" %d\n",(Int_t)okJPSI);
2375  // select D0->Kpi from Dstar
2376  if(fDstar) {
2377  okD0fromDstar = (Bool_t)fCutsDStartoKpipi->IsD0FromDStarSelected(the2Prong->Pt(),the2Prong,AliRDHFCuts::kCandidate);
2378  if(okD0fromDstar) the2Prong->SetSelectionBit(AliRDHFCuts::kD0fromDstarCuts);
2379  }
2380  //if(fDebug && fDstar) printf(" %d\n",(Int_t)okD0fromDstar);
2381  }
2382  }else{
2383  the2Prong =rd;
2384  the2Prong->SetSecondaryVtx(secVert);
2385  secVert->SetParent(the2Prong);
2386  AddDaughterRefs(secVert,(AliAODEvent*)event,twoTrackArray);
2387  the2Prong->SetOwnPrimaryVtx(primVertexAOD);
2388  the2Prong->SetPxPyPzProngs(2,px,py,pz);
2389  the2Prong->SetDCA(dca);
2390  the2Prong->Setd0Prongs(2,d0);
2391  the2Prong->Setd0errProngs(2,d0err);
2392  the2Prong->SetCharge(0);
2393  }
2394  if(primVertexAOD){ delete primVertexAOD; primVertexAOD=NULL;}
2395 
2396  // remove the primary vertex (was used only for selection)
2397  if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx && !fMixEvent && !callFromCascade) {
2398  the2Prong->UnsetOwnPrimaryVtx();
2399  }
2400 
2401  // get PID info from ESD
2402  Double_t esdpid0[5]={0.,0.,0.,0.,0.};
2403  if(postrack->GetStatus()&AliESDtrack::kESDpid) postrack->GetESDpid(esdpid0);
2404  Double_t esdpid1[5]={0.,0.,0.,0.,0.};
2405  if(negtrack->GetStatus()&AliESDtrack::kESDpid) negtrack->GetESDpid(esdpid1);
2406  Double_t esdpid[10];
2407  for(Int_t i=0;i<5;i++) {
2408  esdpid[i] = esdpid0[i];
2409  esdpid[5+i] = esdpid1[i];
2410  }
2411  the2Prong->SetPID(2,esdpid);
2412  return the2Prong;
2413 }
2414 //----------------------------------------------------------------------------
2416  TObjArray *threeTrackArray,AliVEvent *event,
2417  AliAODVertex *secVert,Double_t dispersion,
2418  const AliAODVertex *vertexp1n1, TObjArray *twoTrackArray2,
2419  Double_t dcap1n1,Double_t dcap2n1,Double_t dcap1p2,
2420  Bool_t useForLc, Bool_t useForDs, Bool_t &ok3Prong)
2421 {
2424  // E.Bruna, F.Prino
2425  // AliCodeTimerAuto("",0);
2426 
2427 
2428  UInt_t ntref=TProcessID::GetObjectCount();
2429  if(ntref>16776216){// This number is 2^24-1000. The maximum number of TRef for a given TProcesssID is 2^24=16777216.
2430  AliFatal(Form("Number of TRef created (=%d), close to limit (16777216)",ntref));
2431  }
2432 
2433  ok3Prong=kFALSE;
2434  if(!secVert) return 0x0;
2435 
2436  Double_t px[3],py[3],pz[3],d0[3],d0err[3];
2437  Double_t momentum[3];
2438 
2439 
2440  AliESDtrack *postrack1 = (AliESDtrack*)threeTrackArray->UncheckedAt(0);
2441  AliESDtrack *negtrack = (AliESDtrack*)threeTrackArray->UncheckedAt(1);
2442  AliESDtrack *postrack2 = (AliESDtrack*)threeTrackArray->UncheckedAt(2);
2443 
2444  GetTrackMomentumAtSecVert(postrack1,secVert,momentum);
2445  px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
2446  GetTrackMomentumAtSecVert(negtrack,secVert,momentum);
2447  px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
2448  GetTrackMomentumAtSecVert(postrack2,secVert,momentum);
2449  px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2];
2450 
2451  // invariant mass cut for D+, Ds, Lc
2452  Bool_t okMassCut=kFALSE;
2453  if(fMassCutBeforeVertexing) okMassCut=kTRUE; // mass cut already done and passed
2454  if(!okMassCut && f3Prong) if(SelectInvMassAndPt3prong(px,py,pz)) okMassCut=kTRUE;
2455  if(!okMassCut) {
2456  //AliDebug(2," candidate didn't pass mass cut");
2457  return 0x0;
2458  }
2459 
2460  // primary vertex to be used by this candidate
2461  AliAODVertex *primVertexAOD = 0x0;
2462  Double_t pos[3];
2464  Float_t d0z0f[2],covd0z0f[3];
2465  postrack1->GetImpactParameters(d0z0f,covd0z0f);
2466  d0[0]=d0z0f[0];
2467  d0err[0] = TMath::Sqrt(covd0z0f[0]);
2468  negtrack->GetImpactParameters(d0z0f,covd0z0f);
2469  d0[1]=d0z0f[0];
2470  d0err[1] = TMath::Sqrt(covd0z0f[0]);
2471  postrack2->GetImpactParameters(d0z0f,covd0z0f);
2472  d0[2]=d0z0f[0];
2473  d0err[2] = TMath::Sqrt(covd0z0f[0]);
2474  fV1->GetXYZ(pos);
2475  }else{
2476  primVertexAOD = PrimaryVertex(threeTrackArray,event);
2477  if(!primVertexAOD) return 0x0;
2478  Double_t d0z0[2],covd0z0[3];
2479  postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2480  d0[0]=d0z0[0];
2481  d0err[0] = TMath::Sqrt(covd0z0[0]);
2482  negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2483  d0[1]=d0z0[0];
2484  d0err[1] = TMath::Sqrt(covd0z0[0]);
2485  postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2486  d0[2]=d0z0[0];
2487  d0err[2] = TMath::Sqrt(covd0z0[0]);
2488  primVertexAOD->GetXYZ(pos);
2489  }
2490 
2491  Double_t dca[3]={dcap1n1,dcap2n1,dcap1p2};
2492  Double_t dist12=TMath::Max(0.,fCutsLctopKpi->GetMaxDistanceSecPrimVertex()-0.001);
2493  Double_t dist23=dist12;
2494  Short_t charge=(Short_t)(postrack1->Charge()+postrack2->Charge()+negtrack->Charge());
2495 
2496 
2497  // construct the candidate passing a NULL pointer for the secondary vertex to avoid creation of TRef
2498  AliAODRecoDecayHF3Prong *the3Prong = new AliAODRecoDecayHF3Prong(0x0,px,py,pz,d0,d0err,dca,dispersion,dist12,dist23,charge);
2499  // add a pointer to the secondary vertex via SetOwnSecondaryVtx (no TRef created)
2500  AliAODVertex* ownsecv=secVert->CloneWithoutRefs();
2501  the3Prong->SetOwnSecondaryVtx(ownsecv);
2502  UShort_t id[3]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack->GetID(),(UShort_t)postrack2->GetID()};
2503  the3Prong->SetProngIDs(3,id);
2504  if(primVertexAOD){
2505  the3Prong->SetOwnPrimaryVtx(primVertexAOD);
2506  delete primVertexAOD; primVertexAOD=NULL;
2507  }else{
2508  the3Prong->SetOwnPrimaryVtx(fV1AOD);
2509  }
2510  // disable PID, which requires the TRefs to the daughter tracks
2511  fCutsDplustoKpipi->SetUsePID(kFALSE);
2512  fCutsDstoKKpi->SetUsePID(kFALSE);
2513  fCutsLctopKpi->SetUsePID(kFALSE);
2514 
2515  // select D+->Kpipi, Ds->KKpi, Lc->pKpi
2516  if(f3Prong) {
2517  ok3Prong = kFALSE;
2518 
2520  ok3Prong = kTRUE;
2522  }
2523  if(useForDs && fOKInvMassDs){
2525  ok3Prong = kTRUE;
2527  }
2528  }
2529  if(useForLc && fOKInvMassLc){
2531  ok3Prong = kTRUE;
2533  }
2534  }
2535  }
2536  //if(fDebug) printf("ok3Prong: %d\n",(Int_t)ok3Prong);
2537  the3Prong->UnsetOwnSecondaryVtx();
2539  the3Prong->UnsetOwnPrimaryVtx();
2540  }
2541 
2542  // Add TRefs to secondary vertex and daughter tracks only for candidates passing the filtering cuts
2543  if(ok3Prong && fInputAOD){
2544  the3Prong->SetSecondaryVtx(secVert);
2545  AddDaughterRefs(secVert,(AliAODEvent*)event,threeTrackArray);
2546  Double_t dummyDisp;
2547  AliAODVertex *vertexp2n1 = ReconstructSecondaryVertex(twoTrackArray2,dummyDisp);
2548  if(!vertexp2n1) ok3Prong=kFALSE;
2549  else{
2550  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]));
2551  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]));
2552  the3Prong->SetDist12toPrim(dist12);
2553  the3Prong->SetDist23toPrim(dist23);
2554  delete vertexp2n1;
2555  }
2556  }
2557 
2558  // get PID info from ESD
2559  Double_t esdpid0[5]={0.,0.,0.,0.,0.};
2560  if(postrack1->GetStatus()&AliESDtrack::kESDpid) postrack1->GetESDpid(esdpid0);
2561  Double_t esdpid1[5]={0.,0.,0.,0.,0.};
2562  if(negtrack->GetStatus()&AliESDtrack::kESDpid) negtrack->GetESDpid(esdpid1);
2563  Double_t esdpid2[5]={0.,0.,0.,0.,0.};
2564  if(postrack2->GetStatus()&AliESDtrack::kESDpid) postrack2->GetESDpid(esdpid2);
2565 
2566  Double_t esdpid[15];
2567  for(Int_t i=0;i<5;i++) {
2568  esdpid[i] = esdpid0[i];
2569  esdpid[5+i] = esdpid1[i];
2570  esdpid[10+i] = esdpid2[i];
2571  }
2572  the3Prong->SetPID(3,esdpid);
2573 
2574  return the3Prong;
2575 }
2576 //----------------------------------------------------------------------------
2578  TObjArray *threeTrackArray,AliVEvent *event,
2579  AliAODVertex *secVert,Double_t dispersion,
2580  Double32_t dist12, Double32_t dist23,
2581  Double_t dcap1n1,Double_t dcap2n1,Double_t dcap1p2,
2583 {
2584  // Fill on-the-fly the 3prong data member missing info
2585  // set TRef of vertex and daughters
2586  // do not recalculate the two-track secondary vertex dist12 and dist23
2587  // because they are stored in the AliAODRecoDecayHF3Prong candidate
2588  // reconstructed in the FindCandidate step
2589  // do not check if it is a Lambdac, Ds or Dplus because it is already check in the FindCandidate step
2590  // and the info is stored
2591  // AliCodeTimerAuto("",0);
2592 
2593  UInt_t ntref=TProcessID::GetObjectCount();
2594  if(ntref>16776216){// This number is 2^24-1000. The maximum number of TRef for a given TProcesssID is 2^24=16777216.
2595  AliFatal(Form("Number of TRef created (=%d), close to limit (16777216)",ntref));
2596  }
2597 
2598  Double_t px[3],py[3],pz[3],d0[3],d0err[3];
2599  Double_t momentum[3];
2600 
2601 
2602  AliESDtrack *postrack1 = (AliESDtrack*)threeTrackArray->UncheckedAt(0);
2603  AliESDtrack *negtrack = (AliESDtrack*)threeTrackArray->UncheckedAt(1);
2604  AliESDtrack *postrack2 = (AliESDtrack*)threeTrackArray->UncheckedAt(2);
2605 
2606  postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
2607  negtrack->PropagateToDCA(secVert,fBzkG,kVeryBig);
2608  postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
2609  postrack1->GetPxPyPz(momentum);
2610  px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
2611  negtrack->GetPxPyPz(momentum);
2612  px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
2613  postrack2->GetPxPyPz(momentum);
2614  px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2];
2615  // primary vertex to be used by this candidate
2616  AliAODVertex *primVertexAOD = PrimaryVertex(threeTrackArray,event);
2617  if(!primVertexAOD) return 0x0;
2618  Double_t d0z0[2],covd0z0[3];
2619  postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2620  d0[0]=d0z0[0];
2621  d0err[0] = TMath::Sqrt(covd0z0[0]);
2622  negtrack->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2623  d0[1]=d0z0[0];
2624  d0err[1] = TMath::Sqrt(covd0z0[0]);
2625  postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2626  d0[2]=d0z0[0];
2627  d0err[2] = TMath::Sqrt(covd0z0[0]);
2628 
2629  Double_t pos[3]; primVertexAOD->GetXYZ(pos);
2630  Double_t dca[3]={dcap1n1,dcap2n1,dcap1p2};
2631  Short_t charge=(Short_t)(postrack1->Charge()+postrack2->Charge()+negtrack->Charge());
2632 
2633  rd->SetSecondaryVtx(secVert);
2634  secVert->SetParent(rd);
2635  AddDaughterRefs(secVert,(AliAODEvent*)event,threeTrackArray);
2636 
2637  rd->SetPxPyPzProngs(3,px,py,pz);
2638  rd->SetDCAs(3,dca);
2639  rd->Setd0Prongs(3,d0);
2640  rd->Setd0errProngs(3,d0err);
2641  rd->SetCharge(charge);
2642  rd->SetOwnPrimaryVtx(primVertexAOD);
2643  rd->SetSigmaVert(dispersion);
2644  delete primVertexAOD; primVertexAOD=NULL;
2645 
2647  rd->UnsetOwnPrimaryVtx();
2648  }
2649 
2650  // get PID info from ESD
2651  Double_t esdpid0[5]={0.,0.,0.,0.,0.};
2652  if(postrack1->GetStatus()&AliESDtrack::kESDpid) postrack1->GetESDpid(esdpid0);
2653  Double_t esdpid1[5]={0.,0.,0.,0.,0.};
2654  if(negtrack->GetStatus()&AliESDtrack::kESDpid) negtrack->GetESDpid(esdpid1);
2655  Double_t esdpid2[5]={0.,0.,0.,0.,0.};
2656  if(postrack2->GetStatus()&AliESDtrack::kESDpid) postrack2->GetESDpid(esdpid2);
2657 
2658  Double_t esdpid[15];
2659  for(Int_t i=0;i<5;i++) {
2660  esdpid[i] = esdpid0[i];
2661  esdpid[5+i] = esdpid1[i];
2662  esdpid[10+i] = esdpid2[i];
2663  }
2664  rd->SetPID(3,esdpid);
2665  return rd;
2666 }
2667 //----------------------------------------------------------------------------
2669  TObjArray *fourTrackArray,AliVEvent *event,
2670  AliAODVertex *secVert,
2671  const AliAODVertex *vertexp1n1,
2672  const AliAODVertex *vertexp1n1p2,
2673  Double_t dcap1n1,Double_t dcap1n2,
2674  Double_t dcap2n1,Double_t dcap2n2,
2675  Bool_t &ok4Prong)
2676 {
2679  // G.E.Bruno, R.Romita
2680  // AliCodeTimerAuto("",0);
2681 
2682  UInt_t ntref=TProcessID::GetObjectCount();
2683  if(ntref>16776216){// This number is 2^24-1000. The maximum number of TRef for a given TProcesssID is 2^24=16777216.
2684  AliFatal(Form("Number of TRef created (=%d), close to limit (16777216)",ntref));
2685  }
2686 
2687  ok4Prong=kFALSE;
2688  if(!secVert || !vertexp1n1 || !vertexp1n1p2) return 0x0;
2689 
2690  Double_t px[4],py[4],pz[4],d0[4],d0err[4];//d0z[3];
2691 
2692  AliESDtrack *postrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(0);
2693  AliESDtrack *negtrack1 = (AliESDtrack*)fourTrackArray->UncheckedAt(1);
2694  AliESDtrack *postrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(2);
2695  AliESDtrack *negtrack2 = (AliESDtrack*)fourTrackArray->UncheckedAt(3);
2696 
2697  postrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
2698  negtrack1->PropagateToDCA(secVert,fBzkG,kVeryBig);
2699  postrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
2700  negtrack2->PropagateToDCA(secVert,fBzkG,kVeryBig);
2701 
2702  Double_t momentum[3];
2703  postrack1->GetPxPyPz(momentum);
2704  px[0] = momentum[0]; py[0] = momentum[1]; pz[0] = momentum[2];
2705  negtrack1->GetPxPyPz(momentum);
2706  px[1] = momentum[0]; py[1] = momentum[1]; pz[1] = momentum[2];
2707  postrack2->GetPxPyPz(momentum);
2708  px[2] = momentum[0]; py[2] = momentum[1]; pz[2] = momentum[2];
2709  negtrack2->GetPxPyPz(momentum);
2710  px[3] = momentum[0]; py[3] = momentum[1]; pz[3] = momentum[2];
2711 
2712  // invariant mass cut for rho or D0 (try to improve coding here..)
2713  Bool_t okMassCut=kFALSE;
2714  if(fMassCutBeforeVertexing) okMassCut=kTRUE; // mass cut already done and passed
2715  if(!okMassCut && !(fCutsD0toKpipipi->GetUsePID())) { //no PID, to be implemented with PID
2716  if(SelectInvMassAndPt4prong(px,py,pz)) okMassCut=kTRUE;
2717  }
2718  if(!okMassCut) {
2719  //if(fDebug) printf(" candidate didn't pass mass cut\n");
2720  //printf(" candidate didn't pass mass cut\n");
2721  return 0x0;
2722  }
2723 
2724  // primary vertex to be used by this candidate
2725  AliAODVertex *primVertexAOD = PrimaryVertex(fourTrackArray,event);
2726  if(!primVertexAOD) return 0x0;
2727 
2728  Double_t d0z0[2],covd0z0[3];
2729  postrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2730  d0[0]=d0z0[0];
2731  d0err[0] = TMath::Sqrt(covd0z0[0]);
2732  negtrack1->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2733  d0[1]=d0z0[0];
2734  d0err[1] = TMath::Sqrt(covd0z0[0]);
2735  postrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2736  d0[2]=d0z0[0];
2737  d0err[2] = TMath::Sqrt(covd0z0[0]);
2738  negtrack2->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
2739  d0[3]=d0z0[0];
2740  d0err[3] = TMath::Sqrt(covd0z0[0]);
2741 
2742 
2743  // create the object AliAODRecoDecayHF4Prong
2744  Double_t pos[3]; primVertexAOD->GetXYZ(pos);
2745  Double_t dca[6]={dcap1n1,0.,dcap1n2,dcap2n1,0.,dcap2n2};
2746  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]));
2747  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]));
2748  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]));
2749  Short_t charge=0;
2750  AliAODRecoDecayHF4Prong *the4Prong = new AliAODRecoDecayHF4Prong(secVert,px,py,pz,d0,d0err,dca,dist12,dist3,dist4,charge);
2751  the4Prong->SetOwnPrimaryVtx(primVertexAOD);
2752  UShort_t id[4]={(UShort_t)postrack1->GetID(),(UShort_t)negtrack1->GetID(),(UShort_t)postrack2->GetID(),(UShort_t)negtrack2->GetID()};
2753  the4Prong->SetProngIDs(4,id);
2754 
2755  delete primVertexAOD; primVertexAOD=NULL;
2756 
2758 
2759 
2761  the4Prong->UnsetOwnPrimaryVtx();
2762  }
2763 
2764 
2765  // get PID info from ESD
2766  Double_t esdpid0[5]={0.,0.,0.,0.,0.};
2767  if(postrack1->GetStatus()&AliESDtrack::kESDpid) postrack1->GetESDpid(esdpid0);
2768  Double_t esdpid1[5]={0.,0.,0.,0.,0.};
2769  if(negtrack1->GetStatus()&AliESDtrack::kESDpid) negtrack1->GetESDpid(esdpid1);
2770  Double_t esdpid2[5]={0.,0.,0.,0.,0.};
2771  if(postrack2->GetStatus()&AliESDtrack::kESDpid) postrack2->GetESDpid(esdpid2);
2772  Double_t esdpid3[5]={0.,0.,0.,0.,0.};
2773  if(negtrack2->GetStatus()&AliESDtrack::kESDpid) negtrack2->GetESDpid(esdpid3);
2774 
2775  Double_t esdpid[20];
2776  for(Int_t i=0;i<5;i++) {
2777  esdpid[i] = esdpid0[i];
2778  esdpid[5+i] = esdpid1[i];
2779  esdpid[10+i] = esdpid2[i];
2780  esdpid[15+i] = esdpid3[i];
2781  }
2782  the4Prong->SetPID(4,esdpid);
2783 
2784  return the4Prong;
2785 }
2786 //----------------------------------------------------------------------------------
2788  //assign and save in fAODMap the index of the AliAODTrack track
2789  //ordering them on the basis of selected criteria
2790 
2791  fAODMapSize = 100000;
2792  fAODMap = new Int_t[fAODMapSize];
2793  AliAODTrack *track=0;
2794  memset(fAODMap,0,sizeof(Int_t)*fAODMapSize);
2795  for(Int_t i=0; i<aod->GetNumberOfTracks(); i++) {
2796  track = dynamic_cast<AliAODTrack*>(aod->GetTrack(i));
2797  if(!track) AliFatal("Not a standard AOD");
2798  // skip pure ITS SA tracks
2799  if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
2800 
2801  // skip tracks without ITS
2802  if(!(track->GetStatus()&AliESDtrack::kITSin)) continue;
2803 
2804  // TEMPORARY: check that the cov matrix is there
2805  Double_t covtest[21];
2806  if(!track->GetCovarianceXYZPxPyPz(covtest)) continue;
2807  //
2808 
2809  Int_t ind = (Int_t)track->GetID();
2810  if (ind>-1 && ind < fAODMapSize) fAODMap[ind] = i;
2811  }
2812  return;
2813 }
2814 //-----------------------------------------------------------------------------
2815 AliAODVertex* AliAnalysisVertexingHF::PrimaryVertex(const TObjArray *trkArray,
2816  AliVEvent *event) const
2817 {
2819  //AliCodeTimerAuto("",0);
2820 
2821  AliESDVertex *vertexESD = 0;
2822  AliAODVertex *vertexAOD = 0;
2823 
2824 
2826  // primary vertex from the input event
2827 
2828  vertexESD = new AliESDVertex(*fV1);
2829 
2830  } else {
2831  // primary vertex specific to this candidate
2832 
2833  Int_t nTrks = trkArray->GetEntriesFast();
2834  AliVertexerTracks *vertexer = new AliVertexerTracks(event->GetMagneticField());
2835 
2837  // recalculating the vertex
2838 
2839  if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraint")) {
2840  Float_t diamondcovxy[3];
2841  event->GetDiamondCovXY(diamondcovxy);
2842  Double_t pos[3]={event->GetDiamondX(),event->GetDiamondY(),0.};
2843  Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.*10.};
2844  AliESDVertex *diamond = new AliESDVertex(pos,cov,1.,1);
2845  vertexer->SetVtxStart(diamond);
2846  delete diamond; diamond=NULL;
2847  if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraintOnlyFitter"))
2848  vertexer->SetOnlyFitter();
2849  }
2850  Int_t skipped[1000];
2851  Int_t nTrksToSkip=0,id;
2852  AliExternalTrackParam *t = 0;
2853  for(Int_t i=0; i<nTrks; i++) {
2854  t = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
2855  id = (Int_t)t->GetID();
2856  if(id<0) continue;
2857  skipped[nTrksToSkip++] = id;
2858  }
2859  // TEMPORARY FIX
2860  // For AOD, skip also tracks without covariance matrix
2861  if(fInputAOD) {
2862  Double_t covtest[21];
2863  for(Int_t j=0; j<event->GetNumberOfTracks(); j++) {
2864  AliVTrack *vtrack = (AliVTrack*)event->GetTrack(j);
2865  if(!vtrack->GetCovarianceXYZPxPyPz(covtest)) {
2866  id = (Int_t)vtrack->GetID();
2867  if(id<0) continue;
2868  skipped[nTrksToSkip++] = id;
2869  }
2870  }
2871  }
2872  for(Int_t ijk=nTrksToSkip; ijk<1000; ijk++) skipped[ijk]=-1;
2873  //
2874  vertexer->SetSkipTracks(nTrksToSkip,skipped);
2875  vertexESD = (AliESDVertex*)vertexer->FindPrimaryVertex(event);
2876 
2877  } else if(fRmTrksFromPrimVtx && nTrks>0) {
2878  // removing the prongs tracks
2879 
2880  TObjArray rmArray(nTrks);
2881  UShort_t *rmId = new UShort_t[nTrks];
2882  AliESDtrack *esdTrack = 0;
2883  AliESDtrack *t = 0;
2884  for(Int_t i=0; i<nTrks; i++) {
2885  t = (AliESDtrack*)trkArray->UncheckedAt(i);
2886  esdTrack = new AliESDtrack(*t);
2887  rmArray.AddLast(esdTrack);
2888  if(esdTrack->GetID()>=0) {
2889  rmId[i]=(UShort_t)esdTrack->GetID();
2890  } else {
2891  rmId[i]=9999;
2892  }
2893  }
2894  Float_t diamondxy[2]={static_cast<Float_t>(event->GetDiamondX()),static_cast<Float_t>(event->GetDiamondY())};
2895  vertexESD = vertexer->RemoveTracksFromVertex(fV1,&rmArray,rmId,diamondxy);
2896  delete [] rmId; rmId=NULL;
2897  rmArray.Delete();
2898 
2899  }
2900 
2901  if(!vertexESD) return vertexAOD;
2902  if(vertexESD->GetNContributors()<=0) {
2903  //AliDebug(2,"vertexing failed");
2904  delete vertexESD; vertexESD=NULL;
2905  return vertexAOD;
2906  }
2907 
2908  delete vertexer; vertexer=NULL;
2909 
2910  }
2911 
2912  // convert to AliAODVertex
2913  Double_t pos[3],cov[6],chi2perNDF;
2914  vertexESD->GetXYZ(pos); // position
2915  vertexESD->GetCovMatrix(cov); //covariance matrix
2916  chi2perNDF = vertexESD->GetChi2toNDF();
2917  delete vertexESD; vertexESD=NULL;
2918 
2919  vertexAOD = new AliAODVertex(pos,cov,chi2perNDF);
2920 
2921  return vertexAOD;
2922 }
2923 //-----------------------------------------------------------------------------
2926 
2927  //printf("Preselections:\n");
2928  // fTrackFilter->Dump();
2929  if(fSecVtxWithKF) {
2930  printf("Secondary vertex with Kalman filter package (AliKFParticle)\n");
2931  } else {
2932  printf("Secondary vertex with AliVertexerTracks\n");
2933  }
2934  if(fRecoPrimVtxSkippingTrks) printf("RecoPrimVtxSkippingTrks\n");
2935  if(fRmTrksFromPrimVtx) printf("RmTrksFromPrimVtx\n");
2936  if(fD0toKpi) {
2937  printf("Reconstruct D0->Kpi candidates with cuts:\n");
2939  }
2940  if(fDstar) {
2941  printf("Reconstruct D*->D0pi candidates with cuts:\n");
2942  if(fFindVertexForDstar) {
2943  printf(" Reconstruct a secondary vertex for the D*\n");
2944  } else {
2945  printf(" Assume the D* comes from the primary vertex\n");
2946  }
2948  }
2949  if(fJPSItoEle) {
2950  printf("Reconstruct J/psi from B candidates with cuts:\n");
2952  }
2953  if(f3Prong) {
2954  printf("Reconstruct 3 prong candidates.\n");
2955  printf(" D+->Kpipi cuts:\n");
2957  printf(" Ds->KKpi cuts:\n");
2959  printf(" Lc->pKpi cuts:\n");
2961  }
2962  if(f4Prong) {
2963  printf("Reconstruct 4 prong candidates.\n");
2964  printf(" D0->Kpipipi cuts:\n");
2966  }
2967  if(fCascades) {
2968  printf("Reconstruct cascade candidates formed with v0s.\n");
2969  printf(" Lc -> k0s P & Lc -> L Pi cuts:\n");
2971  printf(" D+ -> K0s pi cuts:\n");
2973  printf(" Ds -> K0s K cuts:\n");
2975  }
2976 
2977  return;
2978 }
2979 //-----------------------------------------------------------------------------
2981  Double_t &dispersion,Bool_t useTRefArray) const
2982 {
2984  //AliCodeTimerAuto("",0);
2985 
2986  AliESDVertex *vertexESD = 0;
2987  AliAODVertex *vertexAOD = 0;
2988 
2989  if(!fSecVtxWithKF) { // AliVertexerTracks
2990 
2991  fVertexerTracks->SetVtxStart(fV1);
2992  vertexESD = (AliESDVertex*)fVertexerTracks->VertexForSelectedESDTracks(trkArray);
2993 
2994  if(!vertexESD) return vertexAOD;
2995 
2996  if(vertexESD->GetNContributors()!=trkArray->GetEntriesFast()) {
2997  //AliDebug(2,"vertexing failed");
2998  delete vertexESD; vertexESD=NULL;
2999  return vertexAOD;
3000  }
3001 
3002  Double_t vertRadius2=vertexESD->GetX()*vertexESD->GetX()+vertexESD->GetY()*vertexESD->GetY();
3003  if(vertRadius2>8.){
3004  // vertex outside beam pipe, reject candidate to avoid propagation through material
3005  delete vertexESD; vertexESD=NULL;
3006  return vertexAOD;
3007  }
3008 
3009  } else { // Kalman Filter vertexer (AliKFParticle)
3010 
3011  AliKFParticle::SetField(fBzkG);
3012 
3013  AliKFVertex vertexKF;
3014 
3015  Int_t nTrks = trkArray->GetEntriesFast();
3016  for(Int_t i=0; i<nTrks; i++) {
3017  AliESDtrack *esdTrack = (AliESDtrack*)trkArray->At(i);
3018  AliKFParticle daughterKF(*esdTrack,211);
3019  vertexKF.AddDaughter(daughterKF);
3020  }
3021  vertexESD = new AliESDVertex(vertexKF.Parameters(),
3022  vertexKF.CovarianceMatrix(),
3023  vertexKF.GetChi2(),
3024  vertexKF.GetNContributors());
3025 
3026  }
3027 
3028  // convert to AliAODVertex
3029  Double_t pos[3],cov[6],chi2perNDF;
3030  vertexESD->GetXYZ(pos); // position
3031  vertexESD->GetCovMatrix(cov); //covariance matrix
3032  chi2perNDF = vertexESD->GetChi2toNDF();
3033  dispersion = vertexESD->GetDispersion();
3034  delete vertexESD; vertexESD=NULL;
3035 
3036  Int_t nprongs= (useTRefArray ? 0 : trkArray->GetEntriesFast());
3037  vertexAOD = new AliAODVertex(pos,cov,chi2perNDF,0x0,-1,AliAODVertex::kUndef,nprongs);
3038 
3039  return vertexAOD;
3040 }
3041 //-----------------------------------------------------------------------------
3044  //AliCodeTimerAuto("",0);
3045 
3046  Int_t retval=kFALSE;
3047  Double_t momentum[3];
3048  Double_t px[3],py[3],pz[3];
3049  for(Int_t iTrack=0; iTrack<3; iTrack++){
3050  AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
3051  track->GetPxPyPz(momentum);
3052  px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
3053  }
3054  retval = SelectInvMassAndPt3prong(px,py,pz);
3055 
3056  return retval;
3057 }
3058 
3059 //-----------------------------------------------------------------------------
3062  //AliCodeTimerAuto("",0);
3063 
3064  Int_t retval=kFALSE;
3065  Double_t momentum[3];
3066  Double_t px[4],py[4],pz[4];
3067 
3068  for(Int_t iTrack=0; iTrack<4; iTrack++){
3069  AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
3070  track->GetPxPyPz(momentum);
3071  px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
3072  }
3073 
3074  retval = SelectInvMassAndPt4prong(px,py,pz);
3075 
3076  return retval;
3077 }
3078 //-----------------------------------------------------------------------------
3081  //AliCodeTimerAuto("",0);
3082 
3083  Int_t retval=kFALSE;
3084  Double_t momentum[3];
3085  Double_t px[2],py[2],pz[2];
3086 
3087  for(Int_t iTrack=0; iTrack<2; iTrack++){
3088  AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
3089  track->GetPxPyPz(momentum);
3090  px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
3091  }
3092  retval = SelectInvMassAndPtDstarD0pi(px,py,pz);
3093 
3094  return retval;
3095 }
3098  //AliCodeTimerAuto("",0);
3099 
3100  Int_t retval=kFALSE;
3101  Double_t momentum[3];
3102  Double_t px[2],py[2],pz[2];
3103  for(Int_t iTrack=0; iTrack<2; iTrack++){
3104  AliESDtrack *track = (AliESDtrack*)trkArray->UncheckedAt(iTrack);
3105  track->GetPxPyPz(momentum);
3106  px[iTrack] = momentum[0]; py[iTrack] = momentum[1]; pz[iTrack] = momentum[2];
3107  }
3108  retval = SelectInvMassAndPtCascade(px,py,pz);
3109 
3110  return retval;
3111 }
3112 //-----------------------------------------------------------------------------
3114  Double_t *py,
3115  Double_t *pz){
3117  //AliCodeTimerAuto("",0);
3118 
3119  UInt_t pdg2[2];
3120  Int_t nprongs=2;
3121  Double_t minv2,mrange;
3122  Double_t lolim,hilim;
3123  Double_t minPt=0;
3124  Bool_t retval=kFALSE;
3125 
3126  fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
3127  fOKInvMassD0=kFALSE;
3128  // pt cut
3129  Double_t ptcand=TMath::Sqrt(fMassCalc2->Pt2());
3131  if(minPt>0.1)
3132  if(ptcand < minPt) return retval;
3133  // mass cut
3134  Int_t jPtBinZero=fCutsD0toKpi->PtBin(ptcand);
3135  if(jPtBinZero<0) jPtBinZero=0;
3136  mrange=fCutsD0toKpi->GetMassCut(jPtBinZero);
3137  lolim=fMassDzero-mrange;
3138  hilim=fMassDzero+mrange;
3139  pdg2[0]=211; pdg2[1]=321;
3140  minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
3141  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3142  retval=kTRUE;
3143  fOKInvMassD0=kTRUE;
3144  }
3145  pdg2[0]=321; pdg2[1]=211;
3146  minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
3147  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3148  retval=kTRUE;
3149  fOKInvMassD0=kTRUE;
3150  }
3151  return retval;
3152 }
3153 
3154 //-----------------------------------------------------------------------------
3156  Double_t *py,
3157  Double_t *pz){
3159  //AliCodeTimerAuto("",0);
3160 
3161  UInt_t pdg2[2];
3162  Int_t nprongs=2;
3163  Double_t minv2,mrange;
3164  Double_t lolim,hilim;
3165  Double_t minPt=0;
3166  Bool_t retval=kFALSE;
3167 
3168  fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
3169  fOKInvMassJpsi=kFALSE;
3170  // pt cut
3172  if(minPt>0.1)
3173  if(fMassCalc2->Pt2() < minPt*minPt) return retval;
3174  // mass cut
3175  mrange=fCutsJpsitoee->GetMassCut();
3176  lolim=fMassJpsi-mrange;
3177  hilim=fMassJpsi+mrange;
3178 
3179  pdg2[0]=11; pdg2[1]=11;
3180  minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
3181  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3182  retval=kTRUE;
3183  fOKInvMassJpsi=kTRUE;
3184  }
3185 
3186  return retval;
3187 }
3188 //-----------------------------------------------------------------------------
3190  Double_t *py,
3191  Double_t *pz,
3192  Int_t pidLcStatus){
3194  //AliCodeTimerAuto("",0);
3195 
3196  UInt_t pdg3[3];
3197  Int_t nprongs=3;
3198  Double_t minv2,mrange;
3199  Double_t lolim,hilim;
3200  Bool_t retval=kFALSE;
3201 
3202 
3203  fMassCalc3->SetPxPyPzProngs(nprongs,px,py,pz);
3204  fOKInvMassDplus=kFALSE;
3205  fOKInvMassDs=kFALSE;
3206  fOKInvMassLc=kFALSE;
3207  // pt cut
3208  Double_t ptcand=TMath::Sqrt(fMassCalc3->Pt2());
3209  if(fMinPt3Prong>0.1)
3210  if(ptcand < fMinPt3Prong) return retval;
3211 
3212  // D+->Kpipi
3213  Int_t jPtBinPlus=fCutsDplustoKpipi->PtBin(ptcand);
3214  if(jPtBinPlus<0) jPtBinPlus=0;
3215  mrange=fCutsDplustoKpipi->GetMassCut(jPtBinPlus);
3216  lolim=fMassDplus-mrange;
3217  hilim=fMassDplus+mrange;
3218  pdg3[0]=211; pdg3[1]=321; pdg3[2]=211;
3219  minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
3220  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3221  retval=kTRUE;
3222  fOKInvMassDplus=kTRUE;
3223  }
3224 
3225  // Ds+->KKpi
3226  Int_t jPtBinS=fCutsDstoKKpi->PtBin(ptcand);
3227  if(jPtBinS<0) jPtBinS=0;
3228  mrange=fCutsDstoKKpi->GetMassCut(jPtBinS);
3229  lolim=fMassDs-mrange;
3230  hilim=fMassDs+mrange;
3231  Double_t mphirange=1.2*fCutsDstoKKpi->GetPhiMassCut(jPtBinS); // 1.2 to have margin
3232  Double_t lolimphi=fMassPhi-mphirange;
3233  Double_t hilimphi=fMassPhi+mphirange;
3234  for(Int_t ih=0; ih<2; ih++){
3235  if(fOKInvMassDs) break;
3236  Int_t k=ih*2;
3237  pdg3[k]=321; pdg3[1]=321; pdg3[2-k]=211;
3238  minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
3239  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3240  if(ptcand < 4){ // check KK mass for Ds with pt<4 GeV/c
3241  Double_t ee = TMath::Sqrt(fMassK*fMassK+px[k]*px[k]+py[k]*py[k]+pz[k]*pz[k])+TMath::Sqrt(fMassK*fMassK+px[1]*px[1]+py[1]*py[1]+pz[1]*pz[1]);
3242  Double_t mKK2=ee*ee-((px[k]+px[1])*(px[k]+px[1])+(py[k]+py[1])*(py[k]+py[1])+(pz[k]+pz[1])*(pz[k]+pz[1]));
3243  if(mKK2>lolimphi*lolimphi && mKK2<hilimphi*hilimphi){
3244  retval=kTRUE;
3245  fOKInvMassDs=kTRUE;
3246  }
3247  }else{
3248  retval=kTRUE;
3249  fOKInvMassDs=kTRUE;
3250  }
3251  }
3252  }
3253 
3254  // Lc->pKpi
3255  if(ptcand>fCutsLctopKpi->GetMinPtCandidate()){
3256  Int_t jPtBinL=fCutsLctopKpi->PtBin(ptcand);
3257  if(jPtBinL<0) jPtBinL=0;
3258  mrange=fCutsLctopKpi->GetMassCut(jPtBinL);
3259  lolim=fMassLambdaC-mrange;
3260  hilim=fMassLambdaC+mrange;
3261  if(pidLcStatus&1){
3262  pdg3[0]=2212; pdg3[1]=321; pdg3[2]=211;
3263  minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
3264  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3265  retval=kTRUE;
3266  fOKInvMassLc=kTRUE;
3267  }
3268  }
3269  if(pidLcStatus&2 && !fOKInvMassLc){
3270  pdg3[0]=211; pdg3[1]=321; pdg3[2]=2212;
3271  minv2 = fMassCalc3->InvMass2(nprongs,pdg3);
3272  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3273  retval=kTRUE;
3274  fOKInvMassLc=kTRUE;
3275  }
3276  }
3277  }
3278  return retval;
3279 }
3280 
3281 //-----------------------------------------------------------------------------
3283  Double_t *py,
3284  Double_t *pz){
3286  //AliCodeTimerAuto("",0);
3287 
3288  UInt_t pdg2[2];
3289  Int_t nprongs=2;
3290  Double_t minv2,mrange;
3291  Double_t lolim,hilim;
3292  Double_t minPt=0;
3293  Bool_t retval=kFALSE;
3294 
3295  fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
3296  fOKInvMassDstar=kFALSE;
3297  // pt cut
3298  Double_t ptcand=TMath::Sqrt(fMassCalc2->Pt2());
3300  if(minPt>0.1)
3301  if(ptcand < minPt) return retval;
3302  // mass cut
3303  Int_t jPtBinStar=fCutsDStartoKpipi->PtBin(ptcand);
3304  if(jPtBinStar<0) jPtBinStar=0;
3305  mrange=fCutsDStartoKpipi->GetMassCut(jPtBinStar);
3306  lolim=fMassDstar-mrange;
3307  hilim=fMassDstar+mrange;
3308  pdg2[0]=211; pdg2[1]=421; // in twoTrackArrayCasc we put the pion first
3309  minv2 = fMassCalc2->InvMass2(nprongs,pdg2);
3310  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3311  retval=kTRUE;
3312  fOKInvMassDstar=kTRUE;
3313  }
3314 
3315  return retval;
3316 }
3317 
3318 //-----------------------------------------------------------------------------
3320  Double_t *py,
3321  Double_t *pz){
3323  //AliCodeTimerAuto("",0);
3324 
3325  UInt_t pdg4[4];
3326  Int_t nprongs=4;
3327  Double_t minv2,mrange;
3328  Double_t lolim,hilim;
3329  Double_t minPt=0;
3330  Bool_t retval=kFALSE;
3331 
3332  // D0->Kpipipi without PID
3333  fMassCalc4->SetPxPyPzProngs(nprongs,px,py,pz);
3334  fOKInvMassD0to4p=kFALSE;
3335  // pt cut
3337  if(minPt>0.1)
3338  if(fMassCalc4->Pt2() < minPt*minPt) return retval;
3339  // mass cut
3340  mrange=fCutsD0toKpipipi->GetMassCut();
3341  lolim=fMassDzero-mrange;
3342  hilim=fMassDzero+mrange;
3343 
3344  pdg4[0]=321; pdg4[1]=211; pdg4[2]=211; pdg4[3]=211;
3345  minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
3346  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3347  retval=kTRUE;
3348  fOKInvMassD0to4p=kTRUE;
3349  }
3350 
3351  pdg4[0]=211; pdg4[1]=321; pdg4[2]=211; pdg4[3]=211;
3352  minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
3353  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3354  retval=kTRUE;
3355  fOKInvMassD0to4p=kTRUE;
3356  }
3357 
3358  pdg4[0]=211; pdg4[1]=211; pdg4[2]=321; pdg4[3]=211;
3359  minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
3360  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3361  retval=kTRUE;
3362  fOKInvMassD0to4p=kTRUE;
3363  }
3364 
3365  pdg4[0]=211; pdg4[1]=211; pdg4[2]=211; pdg4[3]=321;
3366  minv2 = fMassCalc4->InvMass2(nprongs,pdg4);
3367  if(minv2>lolim*lolim && minv2<hilim*hilim ){
3368  retval=kTRUE;
3369  fOKInvMassD0to4p=kTRUE;
3370  }
3371 
3372  return retval;
3373 }
3374 //-----------------------------------------------------------------------------
3376  Double_t *py,
3377  Double_t *pz){
3379  //AliCodeTimerAuto("",0);
3380 
3381  UInt_t pdg2[2];
3382  Int_t nprongs=2;
3383  Double_t minv2,mrange;
3384  Double_t lolim,hilim;
3385  Double_t minPt=0;
3386  Bool_t retval=kFALSE;
3387 
3388  fMassCalc2->SetPxPyPzProngs(nprongs,px,py,pz);
3389  minPt=fCutsLctoV0->GetMinPtCandidate();
3390  if(minPt>0.1)
3391  if(fMassCalc2->Pt2() < minPt*minPt) return retval;
3392 
3393  fOKInvMassLctoV0 = kFALSE;
3394 
3395  // LambdaC candidate
3396  if (fCutsLctoV0) {
3397  mrange = fCutsLctoV0->GetMassCut();
3398  lolim = fMassLambdaC - mrange;
3399  hilim = fMassLambdaC + mrange;
3400  pdg2[0] = 2212; pdg2[1] = 310;
3401  minv2 = fMassCalc2->InvMass2(2, pdg2);
3402  if ((minv2 > lolim*lolim) && (minv2 < hilim*hilim)) {
3403  retval = kTRUE;
3404  fOKInvMassLctoV0 = kTRUE;
3405  }
3406  pdg2[0] = 211; pdg2[1] = 3122;
3407  minv2 = fMassCalc2->InvMass2(2, pdg2);
3408  if ((minv2>lolim*lolim) && (minv2<hilim*hilim)) {
3409  retval = kTRUE;
3410  fOKInvMassLctoV0 = kTRUE;
3411  }
3412  }
3413 
3414  // D+ cascade candidate
3415  if (fCutsDplustoK0spi) {
3416  mrange = fCutsDplustoK0spi->GetMassCut();
3417  lolim = fMassDplus - mrange;
3418  hilim = fMassDplus + mrange;
3419  pdg2[0] = 211; pdg2[1] = 310;
3420  minv2 = fMassCalc2->InvMass2(2, pdg2);
3421  if ((minv2 > lolim*lolim) && (minv2 < hilim*hilim)) {
3422  retval = kTRUE;
3423  }
3424  }
3425 
3426  // Ds cascade candidate
3427  if (fCutsDstoK0sK) {
3428  mrange = fCutsDstoK0sK->GetMassCut();
3429  lolim = fMassDs - mrange;
3430  hilim = fMassDs + mrange;
3431  pdg2[0] = 321; pdg2[1] = 310;
3432  minv2 = fMassCalc2->InvMass2(2, pdg2);
3433  if ((minv2 > lolim*lolim) && (minv2 < hilim*hilim)) {
3434  retval = kTRUE;
3435  }
3436  }
3437 
3438  return retval;
3439 }
3440 //-----------------------------------------------------------------------------
3442  Int_t trkEntries,
3443  TObjArray &seleTrksArray,
3444  TObjArray &tracksAtVertex,
3445  Int_t &nSeleTrks,
3446  UChar_t *seleFlags,Int_t *evtNumber)
3447 {
3453  //AliCodeTimerAuto("",0);
3454 
3455  const AliVVertex *vprimary = event->GetPrimaryVertex();
3456 
3457  if(fV1) { delete fV1; fV1=NULL; }
3458  if(fV1AOD) { delete fV1AOD; fV1AOD=NULL; }
3459  if(fAODMap) { delete [] fAODMap; fAODMap=NULL; }
3460 
3461  Int_t nindices=0;
3462  UShort_t *indices = 0;
3463  Double_t pos[3],cov[6];
3464  const Int_t entries = event->GetNumberOfTracks();
3465  AliCentrality* cent;
3466  vprimary->GetXYZ(pos);
3467  vprimary->GetCovarianceMatrix(cov);
3468  Double_t chi2toNDF = vprimary->GetChi2perNDF();
3469  fV1AOD = new AliAODVertex(pos,cov,chi2toNDF);
3470 
3471  if(!fInputAOD) { // ESD
3472  fV1 = new AliESDVertex(*((AliESDVertex*)vprimary));
3473  cent=((AliESDEvent*)event)->GetCentrality();
3474  } else { // AOD
3475  fV1 = new AliESDVertex(pos,cov,100.,100,vprimary->GetName());
3476  if(entries<=0) return;
3477  indices = new UShort_t[entries];
3478  memset(indices,0,sizeof(UShort_t)*entries);
3479  fAODMapSize = 100000;
3480  fAODMap = new Int_t[fAODMapSize];
3481  memset(fAODMap,0,sizeof(Int_t)*fAODMapSize);
3482  cent=((AliAODEvent*)event)->GetCentrality();
3483  }
3484  Float_t centperc=0.1;
3485  if(event->GetRunNumber()<244824){
3486  centperc=cent->GetCentralityPercentile("V0M");
3487  }else{
3488  AliMultSelection *multSelection = (AliMultSelection * ) event->FindListObject("MultSelection");
3489  if(multSelection){
3490  centperc=multSelection->GetMultiplicityPercentile("V0M");
3491  Int_t qual = multSelection->GetEvSelCode();
3492  if(qual == 199 ) centperc=0.1; // use central cuts as default
3493  }
3494  }
3495  Bool_t okDisplaced=kFALSE,okSoftPi=kFALSE,okFor3Prong=kFALSE,okBachelor=kFALSE;
3496  nSeleTrks=0;
3497 
3498  // transfer ITS tracks from event to arrays
3499  for(Int_t i=0; i<entries; i++) {
3500  AliVTrack *track;
3501  track = (AliVTrack*)event->GetTrack(i);
3502 
3503  // skip pure ITS SA tracks
3504  if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
3505 
3506  // skip tracks without ITS
3507  if(!(track->GetStatus()&AliESDtrack::kITSin)) continue;
3508 
3509  // skip tracks with negative ID
3510  // (these are duplicated TPC-only AOD tracks, for jet analysis...)
3511  if(track->GetID()<0) continue;
3512 
3513  // TEMPORARY: check that the cov matrix is there
3514  Double_t covtest[21];
3515  if(!track->GetCovarianceXYZPxPyPz(covtest)) continue;
3516  //
3517 
3518  if(fInputAOD) {
3519  AliAODTrack *aodt = (AliAODTrack*)track;
3520  if(aodt->GetUsedForPrimVtxFit()) {
3521  indices[nindices]=aodt->GetID(); nindices++;
3522  }
3523  Int_t ind = (Int_t)aodt->GetID();
3524  if (ind>-1 && ind < fAODMapSize) fAODMap[ind] = i;
3525  }
3526 
3527  AliESDtrack *esdt = 0;
3528 
3529  if(!fInputAOD) {
3530  esdt = (AliESDtrack*)track;
3531  } else {
3532  esdt = new AliESDtrack(track);
3533  }
3534 
3535  // single track selection
3536  okDisplaced=kFALSE; okSoftPi=kFALSE; okFor3Prong=kFALSE; okBachelor=kFALSE;
3537  if(fMixEvent && i<trkEntries){
3538  evtNumber[i]=((AliMixedEvent*)event)->EventIndex(i);
3539  const AliVVertex* eventVtx=((AliMixedEvent*)event)->GetEventVertex(i);
3540  Double_t vtxPos[3],primPos[3],primCov[6],trasl[3];
3541  eventVtx->GetXYZ(vtxPos);
3542  vprimary->GetXYZ(primPos);
3543  eventVtx->GetCovarianceMatrix(primCov);
3544  for(Int_t ind=0;ind<3;ind++){
3545  trasl[ind]=vtxPos[ind]-primPos[ind];
3546  }
3547 
3548  Bool_t isTransl=esdt->Translate(trasl,primCov);
3549  if(!isTransl) {
3550  delete esdt;
3551  esdt = NULL;
3552  continue;
3553  }
3554  }
3555 
3556  if(SingleTrkCuts(esdt,centperc,okDisplaced,okSoftPi,okFor3Prong,okBachelor) && nSeleTrks<trkEntries) {
3557  esdt->PropagateToDCA(fV1,fBzkG,kVeryBig);
3558  seleTrksArray.AddLast(esdt);
3559  tracksAtVertex.AddLast(new AliExternalTrackParam(*esdt));
3560  seleFlags[nSeleTrks]=0;
3561  if(okDisplaced) SETBIT(seleFlags[nSeleTrks],kBitDispl);
3562  if(okFor3Prong) SETBIT(seleFlags[nSeleTrks],kBit3Prong);
3563  if(okSoftPi) SETBIT(seleFlags[nSeleTrks],kBitSoftPi);
3564  if(okBachelor) SETBIT(seleFlags[nSeleTrks],kBitBachelor);
3565  // Check the PID
3566  SETBIT(seleFlags[nSeleTrks],kBitPionCompat);
3567  SETBIT(seleFlags[nSeleTrks],kBitKaonCompat);
3568  SETBIT(seleFlags[nSeleTrks],kBitProtonCompat);
3569  Bool_t useTPC=kTRUE;
3570  if(fUseTOFPID){
3571  Double_t nsigmatofPi= fPidResponse->NumberOfSigmasTOF(esdt,AliPID::kPion);
3572  if(nsigmatofPi>-990. && (nsigmatofPi<-fnSigmaTOFPionLow || nsigmatofPi>fnSigmaTOFPionHi)){
3573  CLRBIT(seleFlags[nSeleTrks],kBitPionCompat);
3574  }
3575  Double_t nsigmatofK= fPidResponse->NumberOfSigmasTOF(esdt,AliPID::kKaon);
3576  if(nsigmatofK>-990. && (nsigmatofK<-fnSigmaTOFKaonLow || nsigmatofK>fnSigmaTOFKaonHi)){
3577  CLRBIT(seleFlags[nSeleTrks],kBitKaonCompat);
3578  }
3579  Double_t nsigmatofP= fPidResponse->NumberOfSigmasTOF(esdt,AliPID::kProton);
3580  if(nsigmatofP>-990. && (nsigmatofP<-fnSigmaTOFProtonLow || nsigmatofP>fnSigmaTOFProtonHi)){
3581  CLRBIT(seleFlags[nSeleTrks],kBitProtonCompat);
3582  }
3583  if(fUseTPCPIDOnlyIfNoTOF && nsigmatofPi>-990.) useTPC=kFALSE;
3584  }
3585  if(useTPC && fUseTPCPID && esdt->P()<fMaxMomForTPCPid){
3586  Double_t nsigmatpcPi= fPidResponse->NumberOfSigmasTPC(esdt,AliPID::kPion);
3587  if(nsigmatpcPi>-990. && (nsigmatpcPi<-fnSigmaTPCPionLow || nsigmatpcPi>fnSigmaTPCPionHi)){
3588  CLRBIT(seleFlags[nSeleTrks],kBitPionCompat);
3589  }
3590  Double_t nsigmatpcK= fPidResponse->NumberOfSigmasTPC(esdt,AliPID::kKaon);
3591  if(nsigmatpcK>-990. && (nsigmatpcK<-fnSigmaTPCKaonLow || nsigmatpcK>fnSigmaTPCKaonHi)){
3592  CLRBIT(seleFlags[nSeleTrks],kBitKaonCompat);
3593  }
3594  Double_t nsigmatpcP= fPidResponse->NumberOfSigmasTPC(esdt,AliPID::kProton);
3595  if(nsigmatpcP>-990. && (nsigmatpcP<-fnSigmaTPCProtonLow || nsigmatpcP>fnSigmaTPCProtonHi)){
3596  CLRBIT(seleFlags[nSeleTrks],kBitProtonCompat);
3597  }
3598  }
3599  nSeleTrks++;
3600  } else {
3601  if(fInputAOD) delete esdt;
3602  esdt = NULL;
3603  continue;
3604  }
3605 
3606  } // end loop on tracks
3607 
3608  // primary vertex from AOD
3609  if(fInputAOD) {
3610  delete fV1; fV1=NULL;
3611  Int_t ncontr=nindices;
3612  if(!strcmp(vprimary->GetTitle(),"VertexerTracksWithContraint")) ncontr += 1;
3613  Double_t chi2=chi2toNDF*(2.*(Double_t)ncontr-3.);
3614  fV1 = new AliESDVertex(pos,cov,chi2,ncontr,vprimary->GetName());
3615  fV1->SetTitle(vprimary->GetTitle());
3616  fV1->SetIndices(nindices,indices);
3617  }
3618  if(indices) { delete [] indices; indices=NULL; }
3619 
3620 
3621  return;
3622 }
3623 //-----------------------------------------------------------------------------
3625  //
3627  //
3628  if(fUsePidTag && cuts->GetPidHF()) {
3629  Bool_t usepid=cuts->GetIsUsePID();
3630  cuts->SetUsePID(kTRUE);
3631  if(cuts->IsSelectedPID(rd))
3632  rd->SetSelectionBit(bit);
3633  cuts->SetUsePID(usepid);
3634  }
3635  return;
3636 }
3637 //-----------------------------------------------------------------------------
3639  Float_t centralityperc,
3640  Bool_t &okDisplaced,
3641  Bool_t &okSoftPi,
3642  Bool_t &okFor3Prong,
3643  Bool_t &okBachelor) const
3644 {
3646 
3647  // this is needed to store the impact parameters
3648  //AliCodeTimerAuto("",0);
3649 
3650  if (!trk->PropagateToDCA(fV1,fBzkG,kVeryBig)) return kFALSE;
3651 
3652  trk->RelateToVertex(fV1,fBzkG,kVeryBig);
3653 
3654  UInt_t selectInfo;
3655  //
3656  // Track selection, displaced tracks -- 2 prong
3657  selectInfo = 0;
3658  if(centralityperc>=0 && fMaxCentPercentileForTightCuts>=0
3660  // central PbPb events, tighter cuts
3661  selectInfo = fTrackFilter2prongCentral->IsSelected(trk);
3662  }else{
3663  // standard cuts
3664  if(fTrackFilter) {
3665  selectInfo = fTrackFilter->IsSelected(trk);
3666  }
3667  }
3668  if(selectInfo) okDisplaced=kTRUE;
3669 
3670  // Track selection, displaced tracks -- 3 prong
3671  selectInfo = 0;
3672  if(centralityperc>=0 && fMaxCentPercentileForTightCuts>=0
3674  // central PbPb events, tighter cuts
3675  selectInfo = fTrackFilter3prongCentral->IsSelected(trk);
3676  }else{
3677  // standard cuts
3678  if(fTrackFilter) {
3679  selectInfo = fTrackFilter->IsSelected(trk);
3680  }
3681  }
3682  if(selectInfo) okFor3Prong=kTRUE;
3683 
3684  // Track selection, soft pions
3685  selectInfo = 0;
3686  if(fDstar && fTrackFilterSoftPi) {
3687  selectInfo = fTrackFilterSoftPi->IsSelected(trk);
3688  }
3689  if(selectInfo) okSoftPi=kTRUE;
3690 
3691  // Track selection, bachelor
3692  selectInfo = 0;
3693  if(fCascades){
3695  selectInfo = fTrackFilterBachelor->IsSelected(trk);
3696  }else{
3697  if(okDisplaced) selectInfo=1;
3698  }
3699  }
3700  if(selectInfo) okBachelor=kTRUE;
3701 
3702  if(okDisplaced || okSoftPi || okFor3Prong || okBachelor) return kTRUE;
3703 
3704  return kFALSE;
3705 }
3706 
3707 
3708 //-----------------------------------------------------------------------------
3709 AliAODv0* AliAnalysisVertexingHF::TransformESDv0toAODv0(AliESDv0 *esdV0, TObjArray *twoTrackArrayV0){
3715  //
3716  //AliCodeTimerAuto("",0);
3717  Double_t vertex[3]; esdV0->GetXYZ(vertex[0],vertex[1],vertex[2]);
3718  AliAODVertex *vertexV0 = new AliAODVertex(vertex,esdV0->GetChi2V0(),AliAODVertex::kV0,2);
3719 
3720  // create the v0 neutral track to compute the DCA to the primary vertex
3721  Double_t xyz[3], pxpypz[3];
3722  esdV0->XvYvZv(xyz);
3723  esdV0->PxPyPz(pxpypz);
3724  Double_t cv[21]; for(int i=0; i<21; i++) cv[i]=0;
3725  AliNeutralTrackParam *trackesdV0 = new AliNeutralTrackParam(xyz,pxpypz,cv,0);
3726  if(!trackesdV0) {
3727  delete vertexV0;
3728  return 0;
3729  }
3730  Double_t d0z0[2],covd0z0[3];
3731  AliAODVertex *primVertexAOD = PrimaryVertex();
3732  trackesdV0->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
3733  Double_t dcaV0ToPrimVertex = TMath::Sqrt(covd0z0[0]);
3734  // get the v0 daughters to compute their DCA to the v0 vertex and get their momentum
3735  Double_t dcaV0DaughterToPrimVertex[2];
3736  AliExternalTrackParam *posV0track = (AliExternalTrackParam*)twoTrackArrayV0->UncheckedAt(0);
3737  AliExternalTrackParam *negV0track = (AliExternalTrackParam*)twoTrackArrayV0->UncheckedAt(1);
3738  if( !posV0track || !negV0track) {
3739  if(trackesdV0) {delete trackesdV0; trackesdV0=NULL;}
3740  delete vertexV0;
3741  delete primVertexAOD;
3742  return 0;
3743  }
3744  posV0track->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
3745  // if ( covd0z0[0]<=0.) dcaV0DaughterToPrimVertex[0] = 0;
3746  // else
3747  dcaV0DaughterToPrimVertex[0] = TMath::Sqrt(covd0z0[0]);
3748  negV0track->PropagateToDCA(primVertexAOD,fBzkG,kVeryBig,d0z0,covd0z0);
3749  // if ( covd0z0[0]<=0.)dcaV0DaughterToPrimVertex[1] = 0;
3750  // else
3751  dcaV0DaughterToPrimVertex[1] = TMath::Sqrt(covd0z0[0]);
3752  Double_t dcaV0Daughters = esdV0->GetDcaV0Daughters();
3753  Double_t pmom[3],nmom[3];
3754  esdV0->GetNPxPyPz(nmom[0],nmom[1],nmom[2]);
3755  esdV0->GetPPxPyPz(pmom[0],pmom[1],pmom[2]);
3756 
3757  AliAODv0 *aodV0 = new AliAODv0(vertexV0,dcaV0Daughters,dcaV0ToPrimVertex,pmom,nmom,dcaV0DaughterToPrimVertex);
3758  aodV0->SetOnFlyStatus(esdV0->GetOnFlyStatus());
3759 
3760  delete trackesdV0;
3761  delete primVertexAOD;
3762 
3763  return aodV0;
3764 }
3765 //-----------------------------------------------------------------------------
3766 void AliAnalysisVertexingHF::SetParametersAtVertex(AliESDtrack* esdt, const AliExternalTrackParam* extpar) const{
3768  //AliCodeTimerAuto("",0);
3769 
3770  const Double_t *par=extpar->GetParameter();
3771  const Double_t *cov=extpar->GetCovariance();
3772  Double_t alpha=extpar->GetAlpha();
3773  Double_t x=extpar->GetX();
3774  esdt->Set(x,alpha,par,cov);
3775  return;
3776 }
3777 //-----------------------------------------------------------------------------
3780 
3781  fMassDzero=TDatabasePDG::Instance()->GetParticle(421)->Mass();
3782  fMassDplus=TDatabasePDG::Instance()->GetParticle(411)->Mass();
3783  fMassDs=TDatabasePDG::Instance()->GetParticle(431)->Mass();
3784  fMassLambdaC=TDatabasePDG::Instance()->GetParticle(4122)->Mass();
3785  fMassDstar=TDatabasePDG::Instance()->GetParticle(413)->Mass();
3786  fMassJpsi=TDatabasePDG::Instance()->GetParticle(443)->Mass();
3787  fMassPhi=TDatabasePDG::Instance()->GetParticle(333)->Mass();
3788  fMassK=TDatabasePDG::Instance()->GetParticle(321)->Mass();
3789 }
3790 //-----------------------------------------------------------------------------
3792  //
3794  //
3795 
3796 
3797  //___ Check if the V0 type from AliRDHFCutsLctoV0 is the same as the one set in the ConfigVertexingHF.C for AliAnalysisVertexingHF
3798 
3799 
3801  printf("ERROR: V0 type doesn not match in AliAnalysisVertexingHF (%d) required in AliRDHFCutsLctoV0 (%d)\n",fV0TypeForCascadeVertex,fCutsLctoV0->GetV0Type());
3802  return kFALSE;
3803  }
3804 
3806  printf("ERROR: V0 type doesn not match in AliAnalysisVertexingHF (%d) required in AliRDHfCutsDplustoK0spi (%d)\n",fV0TypeForCascadeVertex,fCutsDplustoK0spi->GetV0Type());
3807  return kFALSE;
3808  }
3809 
3811  printf("ERROR: V0 type doesn not match in AliAnalysisVertexingHF (%d) required in AliRDHFCutsDstoK0sK (%d)\n",fV0TypeForCascadeVertex,fCutsDstoK0sK->GetV0Type());
3812  return kFALSE;
3813  }
3814 
3815  return kTRUE;
3816 }
3817 //-----------------------------------------------------------------------------
3818 
3819 Bool_t AliAnalysisVertexingHF::GetTrackMomentumAtSecVert(AliESDtrack* tr, AliAODVertex* secVert, Double_t momentum[3]) const {
3821 
3822  Double_t alpha=tr->GetAlpha();
3823  Double_t sn=TMath::Sin(alpha), cs=TMath::Cos(alpha);
3824  Double_t x=tr->GetX(), y=tr->GetParameter()[0], snp=tr->GetParameter()[2];
3825  Double_t xv= secVert->GetX()*cs + secVert->GetY()*sn;
3826  Double_t yv=-secVert->GetX()*sn + secVert->GetY()*cs;
3827  x-=xv; y-=yv;
3828  Double_t crv=tr->GetC(fBzkG);
3829  if (TMath::Abs(fBzkG) < kAlmost0Field) crv=0.;
3830  double csp = TMath::Sqrt((1.-snp)*(1.+snp));
3831 
3832  Double_t tgfv=-(crv*x - snp)/(crv*y + csp);
3833  cs = 1./TMath::Sqrt(1+tgfv*tgfv);
3834  sn = cs<1. ? tgfv*cs : 0.;
3835 
3836  x = xv*cs + yv*sn;
3837  Double_t alpNew = alpha+TMath::ASin(sn);
3838  Double_t ca=TMath::Cos(alpNew-alpha), sa=TMath::Sin(alpNew-alpha);
3839  Double_t p2=tr->GetSnp();
3840  Double_t xNew=tr->GetX()*ca + tr->GetY()*sa;
3841  Double_t p2New=p2*ca - TMath::Sqrt((1.- p2)*(1.+p2))*sa;
3842  momentum[0]=tr->GetSigned1Pt();
3843  momentum[1]=p2New*(x-xNew)*tr->GetC(fBzkG);
3844  momentum[2]=tr->GetTgl();
3845  Bool_t retCode=tr->Local2GlobalMomentum(momentum,alpNew);
3846  return retCode;
3847 }
Int_t charge
AliAODRecoDecay * fMassCalc4
for 3 prong
AliAODTrack * GetProng(AliVEvent *event, AliAODRecoDecayHF *rd, Int_t iprong)
Bool_t fUsePidTag
upper momentum limit to apply TPC PID
void SetSelectionBit(Int_t i)
selection map
Int_t PtBin(Float_t pt) const
Definition: AliRDHFCuts.h:330
double Double_t
Definition: External.C:58
void SetupPID(AliVEvent *event)
AliAnalysisFilter * fTrackFilterSoftPi
Track Filter for displaced vertices in PbPb central events (tighter cuts) for 3 prong (D+...
AliVertexerTracks * fVertexerTracks
Float_t GetMassCut(Int_t iPtBin=0) const
AliPIDResponse * fPidResponse
event mixing
AliRDHFCutsDstoK0sK * fCutsDstoK0sK
D+->Kpipi cuts.
AliAODVertex * ReconstructSecondaryVertex(TObjArray *trkArray, Double_t &dispersion, Bool_t useTRefArray=kTRUE) const
Double_t fnSigmaTOFPionHi
Low cut value on n. of sigmas for pi TOF PID.
Double_t fnSigmaTOFProtonHi
Low cut value on n. of sigmas for p TOF PID.
AliAODVertex * PrimaryVertex(const TObjArray *trkArray=0x0, AliVEvent *event=0x0) const
AliAnalysisFilter * fTrackFilter3prongCentral
Track Filter for displaced vertices in PbPb central events (tighter cuts) for 2 prong (D0->Kpi) ...
AliAnalysisVertexingHF & operator=(const AliAnalysisVertexingHF &source)
virtual void PrintAll() const
Float_t GetMassCut(Int_t iPtBin=0) const
AliAODv0 * Getv0() const
AliRDHFCutsDstoKKpi * fCutsDstoKKpi
Ds->K0s+K.
Int_t IsD0FromDStarSelected(Double_t pt, TObject *obj, Int_t selectionLevel, AliAODEvent *aod) const
Bool_t fSecVtxWithKF
z componenent of field in kG
AliRDHFCutsLctopKpi * fCutsLctopKpi
Ds->KKpi cuts.
AliAODVertex * fV1AOD
primary vertex
Bool_t SelectInvMassAndPt3prong(Double_t *px, Double_t *py, Double_t *pz, Int_t pidLcStatus=3)
Int_t fnTrksTotal
triplet fullfilling Lc inv mass selection
virtual Int_t PreSelect(TObjArray aodtracks)
Double_t fnSigmaTOFProtonLow
High cut value on n. of sigmas for p TPC PID.
Bool_t fOKInvMassDplus
pair fullfilling Jpsi inv mass selection
Double_t fnSigmaTPCKaonLow
High cut value on n. of sigmas for pi TOF PID.
Bool_t SingleTrkCuts(AliESDtrack *trk, Float_t centralityperc, Bool_t &okDisplaced, Bool_t &okSoftPi, Bool_t &ok3prong, Bool_t &okBachelor) const
Bool_t FillRecoCand(AliVEvent *event, AliAODRecoDecayHF3Prong *rd3)
Bool_t fUseTPCPIDOnlyIfNoTOF
switch use/not use TOF PID
AliRDHFCutsD0toKpi * fCutsD0toKpi
Track Filter for bachelor.
Bool_t fMixEvent
Like-sign triplets.
virtual void DeleteRecoD()
Float_t GetMassCut(Int_t iPtBin=0) const
Double_t fMinPt3Prong
for 4 prong
Bool_t fUseTOFPID
switch use/not use TPC PID
Bool_t fOKInvMassD0to4p
combination fullfilling D* inv mass selection
Bool_t fOKInvMassLc
triplet fullfilling Ds inv mass selection
Float_t GetMassCut(Int_t iPtBin=0) const
Int_t * fAODMap
map between index and ID for AOD tracks
Double_t fnSigmaTPCPionLow
flag to control usage of PID tagging
Bool_t FillRecoCasc(AliVEvent *event, AliAODRecoCascadeHF *rc, Bool_t isDStar, Bool_t recoSecVtx=kFALSE)
virtual Int_t IsSelectedPID(AliAODRecoDecayHF *)
Definition: AliRDHFCuts.h:321
Bool_t fFindVertexForCascades
reconstruct a secondary vertex or assume it&#39;s from the primary vertex
Double_t fnSigmaTPCKaonHi
Low cut value on n. of sigmas for K TPC PID.
AliAODPidHF * GetPidHF() const
Definition: AliRDHFCuts.h:264
Bool_t fUseKaonPIDfor3Prong
PID response.
AliAODRecoDecayHF2Prong * Make2Prong(TObjArray *twoTrackArray1, AliVEvent *event, AliAODVertex *secVert, Double_t dcap1n1, Bool_t &okD0, Bool_t &okJPSI, Bool_t &okD0fromDstar, Bool_t callFromCascade=kFALSE, Bool_t refill=kFALSE, AliAODRecoDecayHF2Prong *rd=0x0)
AliRDHFCutsDplustoK0spi * fCutsDplustoK0spi
J/psi->ee cuts.
AliRDHFCutsDplustoKpipi * fCutsDplustoKpipi
D+->K0s+pi.
AliRDHFCutsD0toKpipipi * fCutsD0toKpipipi
Lc –> v0 + bachelor cuts.
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel)
Bool_t fLikeSign3prong
Like-sign pairs.
Bool_t SelectInvMassAndPtCascade(Double_t *px, Double_t *py, Double_t *pz)
Bool_t PreSelect(TObject *obj, AliAODv0 *v0, AliVTrack *bachelorTrack)
AliAODRecoDecayHF4Prong * Make4Prong(TObjArray *fourTrackArray, AliVEvent *event, AliAODVertex *secVert, const AliAODVertex *vertexp1n1, const AliAODVertex *vertexp1n1p2, Double_t dcap1n1, Double_t dcap1n2, Double_t dcap2n1, Double_t dcap2n2, Bool_t &ok4Prong)
Class for cuts on AOD reconstructed D+->Kpipi.
Float_t GetDCACut(Int_t iPtBin=0) const
Double_t fnSigmaTPCProtonLow
High cut value on n. of sigmas for K TOF PID.
Float_t GetMinV0PtCut() const
void SetParametersAtVertex(AliESDtrack *esdt, const AliExternalTrackParam *extpar) const
int Int_t
Definition: External.C:63
Float_t GetMassCut(Int_t iPtBin=0) const
Float_t GetDCACut(Int_t iPtBin=0) const
Double_t fMaxMomForTPCPid
use TPC PID only for tracks that without TOF
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel)
unsigned int UInt_t
Definition: External.C:33
Bool_t GetTrackMomentumAtSecVert(AliESDtrack *tr, AliAODVertex *secVert, Double_t momentum[3]) const
Double_t GetMaxDistanceSecPrimVertex() const
Int_t GetIsFilled() const
float Float_t
Definition: External.C:68
Class for cuts on AOD reconstructed Ds->K0S+K.
Float_t GetMassCut(Int_t iPtBin=0) const
Float_t GetMassCut(Int_t iPtBin=0) const
AliAnalysisFilter * fTrackFilter2prongCentral
Track Filter for displaced vertices.
Double_t fnSigmaTOFKaonLow
High cut value on n. of sigmas for K TPC PID.
Float_t GetPhiMassCut(Int_t iPtBin=0) const
Float_t fMaxCentPercentileForTightCuts
High cut value on n. of sigmas for p TOF PID.
AliAODTrack * GetBachelor() const
Bool_t fOKInvMassDstar
triplet fullfilling Lc inv mass selection
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel, AliAODEvent *aod)
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel)
Double_t fBzkG
vertexer, to compute secondary vertices
Float_t GetDCACut(Int_t iPtBin=0) const
Bool_t fUsePIDforLc2V0
PID for Lambdac: 0=no, 1=proton, 2=p and pi.
void SetProngIDs(Int_t nIDs, UShort_t *id)
Class for cuts on AOD reconstructed D+->K0S+pi.
virtual void PrintAll() const
UShort_t GetProngID(Int_t ip) const
Float_t GetMassCut(Int_t iPtBin=0) const
Bool_t fUseKaonPIDforDs
PID for Lambdac 2 V0: 0=no, 1=proton,.
Float_t GetMinV0PtCut() const
Bool_t fUseTPCPID
Kaon PID usage for Ds.
Bool_t fOKInvMassLctoV0
4tracks fullfilling D0 inv mass selection
void SetPrimaryVtxRef(TObject *vtx)
primary vertex
short Short_t
Definition: External.C:23
void SetOwnPrimaryVtx(const AliAODVertex *vtx)
Bool_t fFindVertexForDstar
pointer to list of cuts for output file
Double_t fnSigmaTOFKaonHi
Low cut value on n. of sigmas for K TOF PID.
AliAODRecoDecay * fMassCalc2
to go faster in PbPb
Float_t GetDCACut(Int_t iPtBin=0) const
void FindCandidates(AliVEvent *event, TClonesArray *aodVerticesHFTClArr, TClonesArray *aodD0toKpiTClArr, TClonesArray *aodJPSItoEleTClArr, TClonesArray *aodCharm3ProngTClArr, TClonesArray *aodCharm4ProngTClArr, TClonesArray *aodDstarTClArr, TClonesArray *aodCascadesTClArr, TClonesArray *aodLikeSign2ProngTClArr, TClonesArray *aodLikeSign3ProngTClArr)
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel)
void AddDaughterRefs(AliAODVertex *v, const AliVEvent *event, const TObjArray *trkArray) const
Int_t fUsePIDforLc
Kaon PID usage for 3 prongs.
Bool_t IsEventSelected(AliVEvent *event)
Bool_t fLikeSign
cascades, Lc –> v0+track, D+ –> K0s+Pi, Ds –> K0s+K
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel)
void SetUsePID(Bool_t flag=kTRUE)
Definition: AliRDHFCuts.h:221
virtual void PrintAll() const
Float_t GetDCACut(Int_t iPtBin=0) const
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel)
AliRDHFCutsJpsitoee * fCutsJpsitoee
D0->Kpi cuts.
Bool_t SelectInvMassAndPtJpsiee(Double_t *px, Double_t *py, Double_t *pz)
Bool_t fOKInvMassD0
minimum pt for 3 prong candidates
void Setd0errProngs(Int_t nprongs, Double_t *d0)
Bool_t fOKInvMassJpsi
pair fullfilling D0 inv mass selection
Bool_t SelectInvMassAndPtDstarD0pi(Double_t *px, Double_t *py, Double_t *pz)
Int_t fV0TypeForCascadeVertex
reconstruct a secondary vertex or assume it&#39;s from the primary vertex
unsigned short UShort_t
Definition: External.C:28
AliAnalysisFilter * fTrackFilterBachelor
Track Filter for D* soft pion.
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel)
virtual void PrintAll() const
Bool_t GetIsUsePID() const
Definition: AliRDHFCuts.h:287
AliAODRecoDecayHF3Prong * Make3Prong(TObjArray *threeTrackArray, AliVEvent *event, AliAODVertex *secVert, Double_t dispersion, const AliAODVertex *vertexp1n1, TObjArray *twoTrackArray2, Double_t dcap1n1, Double_t dcap2n1, Double_t dcap1p2, Bool_t useForLc, Bool_t useForDs, Bool_t &ok3Prong)
Bool_t fMassCutBeforeVertexing
Select which V0 type we want to use for the cascas.
Int_t fAODMapSize
input from AOD (kTRUE) or ESD (kFALSE)
void FixReferences(AliAODEvent *aod)
void SetSelectionBitForPID(AliRDHFCuts *cuts, AliAODRecoDecayHF *rd, Int_t bit)
AliAODRecoCascadeHF * MakeCascade(TObjArray *twoTrackArray, AliVEvent *event, AliAODVertex *secVert, AliAODRecoDecayHF2Prong *rd2Prong, Double_t dca, Bool_t &okDstar)
void SelectTracksAndCopyVertex(const AliVEvent *event, Int_t trkEntries, TObjArray &seleTrksArray, TObjArray &tracksAtVertex, Int_t &nSeleTrks, UChar_t *seleFlags, Int_t *evtNumber)
bool Bool_t
Definition: External.C:53
void SetSigmaVert(Double_t sigmaVert)
Bool_t fRecoPrimVtxSkippingTrks
if kTRUE use KF vertexer, else AliVertexerTracks
AliAODRecoDecay * fMassCalc3
for 2 prong
TList * fListOfCuts
Dstar->D0pi cuts.
Bool_t RecoSecondaryVertexForCascades(AliVEvent *event, AliAODRecoCascadeHF *rc)
Float_t GetMassCut(Int_t iPtBin=0) const
Double_t fnSigmaTPCProtonHi
Low cut value on n. of sigmas for p TPC PID.
Double_t GetMinPtCandidate() const
Definition: AliRDHFCuts.h:301
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel)
Float_t GetMassCut(Int_t iPtBin=0) const
AliRDHFCutsLctoV0 * fCutsLctoV0
Lc->pKpi cuts.
Float_t GetDCACut(Int_t iPtBin=0) const
void MapAODtracks(AliVEvent *aod)
AliRDHFCutsDStartoKpipi * fCutsDStartoKpipi
D0->Kpipipi cuts.
AliAnalysisFilter * fTrackFilter
max. centrality percentile for using tight cuts
Float_t GetDCACut(Int_t iPtBin=0) const
Bool_t SelectInvMassAndPtD0Kpi(Double_t *px, Double_t *py, Double_t *pz)
Bool_t GetUsePID(Int_t iPtBin=0) const
AliAODv0 * TransformESDv0toAODv0(AliESDv0 *esdv0, TObjArray *twoTrackArrayV0)
Bool_t SelectInvMassAndPt4prong(Double_t *px, Double_t *py, Double_t *pz)
virtual Int_t IsSelected(TObject *obj, Int_t selectionLevel)
Double_t fnSigmaTPCPionHi
Low cut value on n. of sigmas for pi TPC PID.
Bool_t fD0toKpi
primary vertex (AOD format)
Bool_t fOKInvMassDs
triplet fullfilling D+ inv mass selection
void SetIsFilled(Int_t filled)
void AddRefs(AliAODVertex *v, AliAODRecoDecayHF *rd, const AliVEvent *event, const TObjArray *trkArray) const
Double_t fnSigmaTOFPionLow
High cut value on n. of sigmas for pi TPC PID.