1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 // Secondary vertexing construction Class
17 // Construct secondary vertex from Beauty hadron with electron and
18 // hadrons, then apply selection criteria
21 // MinJung Kweon <minjung@physi.uni-heidelberg.de>
25 #include <TIterator.h>
26 #include <TParticle.h>
28 #include <AliESDVertex.h>
29 #include <AliESDEvent.h>
30 #include <AliAODEvent.h>
31 #include <AliVTrack.h>
32 #include <AliESDtrack.h>
33 #include <AliAODTrack.h>
34 #include "AliHFEsecVtx.h"
35 #include <AliKFParticle.h>
36 #include <AliKFVertex.h>
38 #include <AliMCEvent.h>
39 #include <AliAODMCParticle.h>
40 #include "AliHFEpairs.h"
41 #include "AliHFEsecVtxs.h"
42 #include "AliHFEtrackFilter.h"
44 ClassImp(AliHFEsecVtx)
46 //_______________________________________________________________________________________________
47 AliHFEsecVtx::AliHFEsecVtx():
84 // Default constructor
90 //_______________________________________________________________________________________________
91 AliHFEsecVtx::AliHFEsecVtx(const AliHFEsecVtx &p):
97 ,fUseMCPID(p.fUseMCPID)
99 ,fNparents(p.fNparents)
103 ,fNoOfHFEpairs(p.fNoOfHFEpairs)
104 ,fNoOfHFEsecvtxs(p.fNoOfHFEsecvtxs)
105 ,fArethereSecVtx(p.fArethereSecVtx)
114 ,fSignedLxy(p.fSignedLxy)
115 ,fSignedLxy2(p.fSignedLxy2)
117 ,fInvmass(p.fInvmass)
118 ,fInvmassSigma(p.fInvmassSigma)
121 ,fNsectrk2prim(p.fNsectrk2prim)
122 ,fVtxchi2Tightcut(p.fVtxchi2Tightcut)
123 ,fVtxchi2Loosecut(p.fVtxchi2Loosecut)
131 fFilter = new AliHFEtrackFilter(*p.fFilter);
134 //_______________________________________________________________________________________________
136 AliHFEsecVtx::operator=(const AliHFEsecVtx &)
139 // Assignment operator
142 AliInfo("Not yet implemented.");
146 //_______________________________________________________________________________________________
147 AliHFEsecVtx::~AliHFEsecVtx()
153 //cout << "Analysis Done." << endl;
157 //__________________________________________
158 void AliHFEsecVtx::Init()
161 // set pdg code and index
166 fParentSelect[0][0] = 411;
167 fParentSelect[0][1] = 421;
168 fParentSelect[0][2] = 431;
169 fParentSelect[0][3] = 4122;
170 fParentSelect[0][4] = 4132;
171 fParentSelect[0][5] = 4232;
172 fParentSelect[0][6] = 4332;
174 fParentSelect[1][0] = 511;
175 fParentSelect[1][1] = 521;
176 fParentSelect[1][2] = 531;
177 fParentSelect[1][3] = 5122;
178 fParentSelect[1][4] = 5132;
179 fParentSelect[1][5] = 5232;
180 fParentSelect[1][6] = 5332;
182 // momentum ranges to apply pt dependent cuts
191 // momentum dependent DCA cut values (preliminary)
199 fFilter = new AliHFEtrackFilter("SecVtxFilter");
200 fFilter->MakeCutStepRecKineITSTPC();
201 fFilter->MakeCutStepPrimary();
204 void AliHFEsecVtx::Process(AliVTrack *signalTrack){
208 if(signalTrack->Pt() < 1.0) return;
209 AliESDtrack *track = dynamic_cast<AliESDtrack *>(signalTrack);
212 AliESDtrack *htrack = 0x0;
214 fFilter->FilterTracks(fESD1);
215 TObjArray *candidates = fFilter->GetFilteredTracks();
216 TIterator *trackIter = candidates->MakeIterator();
217 while((htrack = dynamic_cast<AliESDtrack *>(trackIter->Next()))){
218 if(track->GetID() == htrack->GetID()) continue; // since it is for tagging single electron, don't need additional condition
219 if (htrack->Pt()<1.0) continue;
220 PairAnalysis(track, htrack, htrack->GetID()); // e-h pairing
223 /*for(int ip=0; ip<fSecVtx->HFEpairs()->GetEntriesFast(); ip++){
225 AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip));
226 if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.)) // apply various cuts
227 fSecVtx->HFEpairs()->RemoveAt(ip);
230 HFEpairs()->Compress();
231 RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks
232 for(int ip=0; ip<HFEsecvtxs()->GetEntriesFast(); ip++){
233 AliHFEsecVtxs *secvtx=0x0;
234 secvtx = (AliHFEsecVtxs*) (HFEsecvtxs()->UncheckedAt(ip));
235 // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs()
241 //_______________________________________________________________________________________________
242 void AliHFEsecVtx::CreateHistograms(TList * const qaList)
250 fSecVtxList = qaList;
251 fSecVtxList->SetName("SecVtx");
255 fkSourceLabel[kAll]="all";
256 fkSourceLabel[kDirectCharm]="directCharm";
257 fkSourceLabel[kDirectBeauty]="directBeauty";
258 fkSourceLabel[kBeautyCharm]="beauty2charm";
259 fkSourceLabel[kGamma]="gamma";
260 fkSourceLabel[kPi0]="pi0";
261 fkSourceLabel[kElse]="others";
262 fkSourceLabel[kBeautyGamma]="beauty22gamma";
263 fkSourceLabel[kBeautyPi0]="beauty22pi0";
264 fkSourceLabel[kBeautyElse]="beauty22others";
267 TString hnopt="secvtx_";
268 for (Int_t isource = 0; isource < 10; isource++ ){
272 //qaList->AddLast(fSecVtxList);
275 //_______________________________________________________________________________________________
276 void AliHFEsecVtx::GetPrimaryCondition()
279 // get primary characteristics and set
283 AliKFVertex primVtxCopy(*(fESD1->GetPrimaryVertex()));
284 if( primVtxCopy.GetNDF() <1 ) return;
285 fPVx = primVtxCopy.GetX();
286 fPVy = primVtxCopy.GetY();
289 AliKFVertex primVtxCopy(*(fAOD1->GetPrimaryVertex()));
290 if( primVtxCopy.GetNDF() <1 ) return;
291 fPVx = primVtxCopy.GetX();
292 fPVy = primVtxCopy.GetY();
296 //_______________________________________________________________________________________________
297 void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t index2)
300 // calculate e-h pair characteristics and tag pair
303 //later consider the below
304 Float_t dca1[2]={-999.,-999.}, dca2[2]={-999.,-999.};
305 Float_t cov1[3]={-999.,-999.,-999.}, cov2[3]={-999.,-999.,-999.};
307 Double_t dca1aod[2]={-999.,-999.}, dca2aod[2]={-999.,-999.};
308 Double_t cov1aod[3]={-999.,-999.,-999.}, cov2aod[3]={-999.,-999.,-999.};
310 if (IsAODanalysis()){
311 const AliAODVertex *primVtx = fAOD1->GetPrimaryVertex();
312 AliESDtrack esdTrk1(track1);
313 AliESDtrack esdTrk2(track2);
314 esdTrk1.PropagateToDCA(primVtx,0.,10000.,dca1aod,cov1aod);
315 esdTrk2.PropagateToDCA(primVtx,0.,10000.,dca2aod,cov2aod);
318 ((AliESDtrack*)track1)->GetImpactParameters(dca1,cov1);
319 ((AliESDtrack*)track2)->GetImpactParameters(dca2,cov2);
322 // apply pt dependent dca cut on hadrons
323 /*for(int ibin=0; ibin<6; ibin++){
324 if((track2->Pt()>fPtRng[ibin] && track2->Pt()<fPtRng[ibin+1]) && TMath::Abs(dca2[0])<fDcaCut[ibin]) return;
327 // get KF particle input pid
328 Int_t pdg1 = GetPDG(track1);
329 Int_t pdg2 = GetPDG(track2);
331 if(pdg1==-1 || pdg2==-1) {
332 //printf("out if considered pid range \n");
336 // create KF particle of pair
337 if(IsAODanalysis()) AliKFParticle::SetField(fAOD1->GetMagneticField());
338 else AliKFParticle::SetField(fESD1->GetMagneticField());
340 AliKFParticle kfTrack[2];
341 kfTrack[0] = AliKFParticle(*track1, pdg1);
342 kfTrack[1] = AliKFParticle(*track2, pdg2);
344 AliKFParticle kfSecondary(kfTrack[0],kfTrack[1]);
346 //secondary vertex point from kf particle
347 Double_t kfx = kfSecondary.GetX();
348 Double_t kfy = kfSecondary.GetY();
349 //Double_t kfz = kfSecondary.GetZ();
351 //momentum at the decay point from kf particle
352 Double_t kfpx = kfSecondary.GetPx();
353 Double_t kfpy = kfSecondary.GetPy();
354 //Double_t kfpz = kfSecondary.GetPz();
357 /* //directly use of ESD vertex
358 const AliESDVertex *pvertex = fESD1->GetPrimaryVertex();
360 pvertex->GetXYZ(xyzVtx);
362 Double_t dx = kfx-xyzVtx[0];
363 Double_t dy = kfy-xyzVtx[1];*/
365 AliKFVertex primVtxCopy(*(fESD1->GetPrimaryVertex()));
366 if( primVtxCopy.GetNDF() <1 ) return;
367 fPVx = primVtxCopy.GetX();
368 fPVy = primVtxCopy.GetY();
370 // printf("esdx= %lf kfx= %lf esdy= %lf kfy= %lf\n",xyzVtx[0],fPVx,xyzVtx[1],fPVy);
372 Double_t dx = kfx-fPVx;
373 Double_t dy = kfy-fPVy;
375 // discriminating variables
376 // invariant mass of the KF particle
377 Double_t invmass = -1;
378 Double_t invmassSigma = -1;
379 kfSecondary.GetMass(invmass,invmassSigma);
381 // chi2 of the KF particle
382 Double_t kfchi2 = -1;
383 if(kfSecondary.GetNDF()>0) kfchi2 = TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF()));
385 // opening angle between two particles in XY plane
386 Double_t phi = kfTrack[0].GetAngleXY(kfTrack[1]);
387 Double_t cosphi = TMath::Cos(phi);
389 // DCA from primary to e-h KF particle (impact parameter of KF particle)
390 Double_t vtx[2]={fPVx, fPVy};
391 Double_t kfip = kfSecondary.GetDistanceFromVertexXY(vtx);
393 // projection of kf vertex vector to the kf momentum direction
394 Double_t signedLxy=-999.;
395 if((dx*kfpx+dy*kfpy)>0) signedLxy = TMath::Sqrt(dx*dx+dy*dy);
396 if((dx*kfpx+dy*kfpy)<0) signedLxy = -1*TMath::Sqrt(dx*dx+dy*dy);
397 //[the other way to think about]
398 //Double_t psqr = kfpx*kfpx+kfpy*kfpy;
399 //if(psqr>0) signedLxy=(dx*kfpx+dy*kfpy)/TMath::Sqrt(psqr);
401 //recalculating primary vertex after removing secvtx tracks --------------------------
403 trkid[0] = track1->GetID();
404 trkid[1] = track2->GetID();
406 RecalcPrimvtx(2, trkid, kfTrack);
407 Double_t dx2 = kfx-fPVx2;
408 Double_t dy2 = kfy-fPVy2;
410 // IP of sec particle recalculated based on recalculated primary vertex
411 Double_t vtx2[2]={fPVx2, fPVy2};
412 Double_t kfip2 = kfSecondary.GetDistanceFromVertexXY(vtx2);
413 // signed Lxy recalculated based on recalculated primary vertex
414 Double_t signedLxy2=-999.;
415 if((dx2*kfpx+dy2*kfpy)>0) signedLxy2 = TMath::Sqrt(dx2*dx2+dy2*dy2);
416 if((dx2*kfpx+dy2*kfpy)<0) signedLxy2 = -1*TMath::Sqrt(dx2*dx2+dy2*dy2);
417 //------------------------------------------------------------------------------------
421 if (HasMCData()) paircode = GetPairCode(track1,track2);
424 hfepair.SetTrkLabel(index2);
425 hfepair.SetInvmass(invmass);
426 hfepair.SetKFChi2(kfchi2);
427 hfepair.SetOpenangle(phi);
428 hfepair.SetCosOpenangle(cosphi);
429 hfepair.SetSignedLxy(signedLxy);
430 hfepair.SetSignedLxy2(signedLxy2);
431 hfepair.SetKFIP(kfip);
432 hfepair.SetKFIP2(kfip2);
433 hfepair.SetPairCode(paircode);
434 AddHFEpairToArray(&hfepair);
437 // fill into container for later QA
445 //if(cov1[0]>0) dataE[6]=Double_t(dca1[0]/cov1[0]);
446 //if(cov2[0]>0) dataE[7]=Double_t(dca2[0]/cov2[0]);
447 //dataE[6]=track1->Pt();
448 //dataE[7]=track2->Pt();
449 //dataE[6]=dca1[0]; //mjtmp
450 //dataE[7]=dca2[0]; //mjtmp
451 //dataE[8]=TMath::Abs(dca1[0]);
452 //dataE[9]=TMath::Abs(dca2[0]);
454 fPairQA->Fill(dataE);
458 //_______________________________________________________________________________________________
459 void AliHFEsecVtx::RunSECVTX(AliVTrack *track)
462 // run secondary vertexing algorithm and do tagging
465 //printf("number of considered pairs= %d\n",HFEpairs()->GetEntriesFast());
466 FindSECVTXCandid(track);
469 //_______________________________________________________________________________________________
470 void AliHFEsecVtx::FindSECVTXCandid(AliVTrack *track)
473 // find secondary vertex candidate and store them into container
476 AliVTrack *htrack[20];
477 //Int_t htracklabel[20];
478 //Int_t paircode[20];
479 //Double_t vtxchi2[20];
480 //Double_t dataE[7]={-999.,-999.,-999.,-999.,-1.,0,0};
482 fVtxchi2Tightcut=3.; // tight cut for pair
483 fVtxchi2Loosecut=5.; // loose cut for secvtx
485 if (HFEpairs()->GetEntriesFast()>20){
486 AliDebug(3, "number of paired hadron is over maximum(20)");
490 // get paired track objects
491 AliHFEpairs *pair=0x0;
492 if (IsAODanalysis()){
493 for (int ip=0; ip<HFEpairs()->GetEntriesFast(); ip++){
494 pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ip));
495 //htracklabel[ip] = pair->GetTrkLabel();
496 htrack[ip] = fAOD1->GetTrack(pair->GetTrkLabel());
497 //if(pair->GetPairCode()==2 || pair->GetPairCode()==3) paircode[ip]=1;
498 //else paircode[ip]=0;
499 //vtxchi2[ip] = pair->GetKFChi2();
503 for (int ip=0; ip<HFEpairs()->GetEntriesFast(); ip++){
504 pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ip));
505 //htracklabel[ip] = pair->GetTrkLabel();
506 htrack[ip] = fESD1->GetTrack(pair->GetTrkLabel());
507 //if(pair->GetPairCode()==2 || pair->GetPairCode()==3) paircode[ip]=1;
508 //else paircode[ip]=0;
509 //vtxchi2[ip] = pair->GetKFChi2();
513 Int_t nPairs = HFEpairs()->GetEntriesFast();
516 // 1 electron candidate + 1 track
518 if (pair->GetKFChi2() < fVtxchi2Tightcut) { // you can also put single track cut -> here you apply very tight cut for the pair
519 Fill2TrkSECVTX(track, pair);
523 //--------------------------------------------------------------
525 // 1 electron candidate + 2 tracks
527 CalcSECVTXProperty(track, htrack[0], htrack[1]); // calculate secondary vertex property
529 if (fKFchi2 < fVtxchi2Loosecut) { // -> here you apply rather loose cut
530 Fill3TrkSECVTX(track, 0, 1);
532 else{ // if doesn't pass the sec vtx chi2 cut
533 for(int jp=0; jp<2; jp++){
534 pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jp));
535 if (pair->GetKFChi2() < fVtxchi2Tightcut){
536 Fill2TrkSECVTX(track, pair);
542 //--------------------------------------------------------------
544 // 1 electron candidate + 3 tracks
546 CalcSECVTXProperty(track, htrack[0], htrack[1], htrack[2]); // calculate secondary vertex property
548 if (fKFchi2 < fVtxchi2Loosecut) {
549 Fill4TrkSECVTX(track, 0, 1, 2);
553 for (int i=0; i<nPairs-1; i++){
554 for (int j=i+1; j<nPairs; j++){
555 CalcSECVTXProperty(track, htrack[i], htrack[j]);
556 if (fKFchi2 < fVtxchi2Loosecut) {
558 Fill3TrkSECVTX(track, i, j);
562 if(!fArethereSecVtx){
563 for(int jp=0; jp<nPairs; jp++){
564 pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jp));
565 if (pair->GetKFChi2() < fVtxchi2Tightcut){
566 Fill2TrkSECVTX(track, pair);
573 //--------------------------------------------------------------
575 // 1 electron candidate + more than 3 tracks
578 for (int ih1=0; ih1<nPairs-2; ih1++){
579 for (int ih2=ih1+1; ih2<nPairs-1; ih2++){
580 for (int ih3=ih2+1; ih3<nPairs; ih3++){
581 CalcSECVTXProperty(track, htrack[ih1], htrack[ih2], htrack[ih3]); // calculate secondary vertex property
582 if (fKFchi2 < fVtxchi2Loosecut) {
584 Fill4TrkSECVTX(track, ih1, ih2, ih3);
589 if (!fArethereSecVtx){
591 for (int i=0; i<nPairs-1; i++){
592 for (int j=i+1; j<nPairs; j++){
593 CalcSECVTXProperty(track, htrack[i], htrack[j]);
594 if (fKFchi2 < fVtxchi2Loosecut) {
596 Fill3TrkSECVTX(track, i, j);
601 if (!fArethereSecVtx){
602 for(int jp=0; jp<nPairs; jp++){
603 pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jp));
604 if (pair->GetKFChi2() < fVtxchi2Tightcut){
605 Fill2TrkSECVTX(track, pair);
611 //--------------------------------------------------------------
615 //_______________________________________________________________________________________________
616 void AliHFEsecVtx::Fill4TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair, Int_t kpair)
619 // fill 3 tracks' secondary vertex properties
622 Double_t dataE[9]={-999.,-999.,-999.,-999.,-1.,0,0,-999.,-999.};
624 Int_t paircode1 = 0, paircode2 = 0, paircode3 = 0;
625 Int_t htracklabel1 = 0, htracklabel2= 0;
628 AliHFEpairs *pair1=0x0;
629 AliHFEpairs *pair2=0x0;
630 AliHFEpairs *pair3=0x0;
631 pair1 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ipair));
632 pair2 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jpair));
633 pair3 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(kpair));
635 htracklabel1 = pair1->GetTrkLabel();
636 htracklabel2 = pair2->GetTrkLabel();
638 if (pair1->GetPairCode()==2 || pair1->GetPairCode()==3) paircode1=1;
640 if (pair2->GetPairCode()==2 || pair2->GetPairCode()==3) paircode2=1;
642 if (pair3->GetPairCode()==2 || pair3->GetPairCode()==3) paircode3=1;
646 AliHFEsecVtxs hfesecvtx;
647 hfesecvtx.SetTrkLabel1(htracklabel1); // mj: not much meaningful for the moment
648 hfesecvtx.SetTrkLabel2(htracklabel2); // mj: not much meaningful for the moment
649 if(HasMCData()) hfesecvtx.SetMCCode(GetElectronSource(TMath::Abs(track->GetLabel())));
650 hfesecvtx.SetKFChi2(fKFchi2);
651 hfesecvtx.SetInvmass(fInvmass);
652 hfesecvtx.SetSignedLxy(fSignedLxy);
653 hfesecvtx.SetSignedLxy2(fSignedLxy2);
654 hfesecvtx.SetKFIP(fKFip);
655 hfesecvtx.SetKFIP2(fKFip2);
656 AddHFEsecvtxToArray(&hfesecvtx);
663 if(HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel()));
664 dataE[5]=4; //# of associated tracks
665 if(paircode1 & paircode2 & paircode3) dataE[6]=1;
666 else if(!paircode1 & !paircode2 & !paircode3) dataE[6]=0;
668 dataE[7]=fSignedLxy2;
669 dataE[8]=track->Pt();
670 fSecvtxQA->Fill(dataE);
673 //_______________________________________________________________________________________________
674 void AliHFEsecVtx::Fill3TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair)
677 // fill 3 tracks' secondary vertex properties
680 Double_t dataE[9]={-999.,-999.,-999.,-999.,-1.,0,0,-999.,-999.};
682 Int_t paircode1 = 0, paircode2 = 0;
683 Int_t htracklabel1 = 0, htracklabel2 = 0;
686 AliHFEpairs *pair1=0x0;
687 AliHFEpairs *pair2=0x0;
688 pair1 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ipair));
689 pair2 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jpair));
691 htracklabel1 = pair1->GetTrkLabel();
692 htracklabel2 = pair2->GetTrkLabel();
694 if (pair1->GetPairCode()==2 || pair1->GetPairCode()==3) paircode1=1;
696 if (pair2->GetPairCode()==2 || pair2->GetPairCode()==3) paircode2=1;
700 // fill secondary vertex container
701 AliHFEsecVtxs hfesecvtx;
702 hfesecvtx.SetTrkLabel1(htracklabel1);
703 hfesecvtx.SetTrkLabel2(htracklabel2);
704 if(HasMCData()) hfesecvtx.SetMCCode(GetElectronSource(TMath::Abs(track->GetLabel())));
705 hfesecvtx.SetKFChi2(fKFchi2);
706 hfesecvtx.SetInvmass(fInvmass);
707 hfesecvtx.SetSignedLxy(fSignedLxy);
708 hfesecvtx.SetSignedLxy2(fSignedLxy2);
709 hfesecvtx.SetKFIP(fKFip);
710 hfesecvtx.SetKFIP2(fKFip2);
711 AddHFEsecvtxToArray(&hfesecvtx);
714 // fill debugging THnSparse
719 if(HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel()));
721 if(paircode1 & paircode2) dataE[6]=1;
722 else if(!paircode1 & !paircode2) dataE[6]=0;
724 dataE[7]=fSignedLxy2;
725 dataE[8]=track->Pt();
726 fSecvtxQA->Fill(dataE);
730 //_______________________________________________________________________________________________
731 void AliHFEsecVtx::Fill2TrkSECVTX(AliVTrack* track, AliHFEpairs *pair)
734 // fill 2 tracks' secondary vertex properties
737 Double_t dataE[9]={-999.,-999.,-999.,-999.,-1.,0,0,-999.,-999.};
740 if (pair->GetPairCode()==2 || pair->GetPairCode()==3) paircode=1;
743 // fill secondary vertex container
744 AliHFEsecVtxs hfesecvtx;
745 hfesecvtx.SetTrkLabel1(pair->GetTrkLabel());
746 hfesecvtx.SetTrkLabel2(-999);
747 if(HasMCData()) hfesecvtx.SetMCCode(GetElectronSource(TMath::Abs(track->GetLabel())));
748 hfesecvtx.SetInvmass(pair->GetInvmass());
749 hfesecvtx.SetKFChi2(pair->GetKFChi2());
750 hfesecvtx.SetSignedLxy(pair->GetSignedLxy());
751 hfesecvtx.SetSignedLxy2(pair->GetSignedLxy2());
752 hfesecvtx.SetKFIP(pair->GetKFIP());
753 hfesecvtx.SetKFIP2(pair->GetKFIP2());
754 AddHFEsecvtxToArray(&hfesecvtx);
757 // fill debugging THnSparse
758 dataE[0]=pair->GetInvmass();
759 dataE[1]=pair->GetKFChi2();
760 dataE[2]=pair->GetSignedLxy();
761 dataE[3]=pair->GetKFIP();
762 if (HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel()));
763 dataE[5]=2; //# of associated tracks
765 dataE[7]=pair->GetSignedLxy2();
766 dataE[8]=track->Pt();
767 fSecvtxQA->Fill(dataE);
771 //_______________________________________________________________________________________________
772 void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliVTrack* track3)
775 // calculate secondary vertex properties
778 // get KF particle input pid
779 Int_t pdg1 = GetPDG(track1);
780 Int_t pdg2 = GetPDG(track2);
781 Int_t pdg3 = GetPDG(track3);
783 if(pdg1==-1 || pdg2==-1 || pdg3==-1) {
784 //printf("out if considered pid range \n");
788 // create KF particle of pair
789 if(IsAODanalysis()) AliKFParticle::SetField(fAOD1->GetMagneticField());
790 else AliKFParticle::SetField(fESD1->GetMagneticField());
791 AliKFParticle kfTrack[3];
792 kfTrack[0] = AliKFParticle(*track1, pdg1);
793 kfTrack[1] = AliKFParticle(*track2, pdg2);
794 kfTrack[2] = AliKFParticle(*track3, pdg3);
796 AliKFParticle kfSecondary(kfTrack[0],kfTrack[1],kfTrack[2]);
797 //AliKFParticle kfSecondary(kfTrack1,kfTrack2,kfTrack3);
799 //secondary vertex point from kf particle
800 Double_t kfx = kfSecondary.GetX();
801 Double_t kfy = kfSecondary.GetY();
802 //Double_t kfz = kfSecondary.GetZ();
804 //momentum at the decay point from kf particle
805 Double_t kfpx = kfSecondary.GetPx();
806 Double_t kfpy = kfSecondary.GetPy();
807 //Double_t kfpz = kfSecondary.GetPz();
809 Double_t dx = kfx-fPVx;
810 Double_t dy = kfy-fPVy;
812 // discriminating variables ----------------------------------------------------------
814 if(kfSecondary.GetNDF()>0) fKFchi2 = TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF()));
816 // invariant mass of the KF particle
817 kfSecondary.GetMass(fInvmass,fInvmassSigma);
819 // DCA from primary to e-h KF particle (impact parameter of KF particle)
820 Double_t vtx[2]={fPVx, fPVy};
821 fKFip = kfSecondary.GetDistanceFromVertexXY(vtx);
823 if((dx*kfpx+dy*kfpy)>0) fSignedLxy= TMath::Sqrt(dx*dx+dy*dy);
824 if((dx*kfpx+dy*kfpy)<0) fSignedLxy= -1*TMath::Sqrt(dx*dx+dy*dy);
825 //[the other way to think about] - projection of kf vertex vector to the kf momentum direction
826 //Double_t psqr = kfpx*kfpx+kfpy*kfpy;
827 //if(psqr>0) fSignedLxy=(dx*kfpx+dy*kfpy)/TMath::Sqrt(psqr);
830 //recalculating primary vertex after removing secvtx tracks --------------------------
832 trkid[0] = track1->GetID();
833 trkid[1] = track2->GetID();
834 trkid[2] = track3->GetID();
836 RecalcPrimvtx(3, trkid, kfTrack);
837 Double_t dx2 = kfx-fPVx2;
838 Double_t dy2 = kfy-fPVy2;
840 // IP of sec particle recalculated based on recalculated primary vertex
841 Double_t vtx2[2]={fPVx2, fPVy2};
842 fKFip2 = kfSecondary.GetDistanceFromVertexXY(vtx2);
843 // signed Lxy recalculated based on recalculated primary vertex
844 if((dx2*kfpx+dy2*kfpy)>0) fSignedLxy2= TMath::Sqrt(dx2*dx2+dy2*dy2);
845 if((dx2*kfpx+dy2*kfpy)<0) fSignedLxy2= -1*TMath::Sqrt(dx2*dx2+dy2*dy2);
846 //------------------------------------------------------------------------------------
850 //_______________________________________________________________________________________________
851 void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliVTrack* track3, AliVTrack* track4)
854 // calculate secondary vertex properties
857 // get KF particle input pid
858 Int_t pdg1 = GetPDG(track1);
859 Int_t pdg2 = GetPDG(track2);
860 Int_t pdg3 = GetPDG(track3);
861 Int_t pdg4 = GetPDG(track4);
863 if(pdg1==-1 || pdg2==-1 || pdg3==-1 || pdg4==-1) {
864 //printf("out if considered pid range \n");
868 // create KF particle of pair
869 if(IsAODanalysis()) AliKFParticle::SetField(fAOD1->GetMagneticField());
870 else AliKFParticle::SetField(fESD1->GetMagneticField());
872 AliKFParticle kfTrack[4];
873 kfTrack[0] = AliKFParticle(*track1, pdg1);
874 kfTrack[1] = AliKFParticle(*track2, pdg2);
875 kfTrack[2] = AliKFParticle(*track3, pdg3);
876 kfTrack[3] = AliKFParticle(*track4, pdg4);
878 AliKFParticle kfSecondary(kfTrack[0],kfTrack[1],kfTrack[2],kfTrack[3]);
880 //secondary vertex point from kf particle
881 Double_t kfx = kfSecondary.GetX();
882 Double_t kfy = kfSecondary.GetY();
883 //Double_t kfz = kfSecondary.GetZ();
885 //momentum at the decay point from kf particle
886 Double_t kfpx = kfSecondary.GetPx();
887 Double_t kfpy = kfSecondary.GetPy();
888 //Double_t kfpz = kfSecondary.GetPz();
890 Double_t dx = kfx-fPVx;
891 Double_t dy = kfy-fPVy;
893 // discriminating variables ----------------------------------------------------------
895 if(kfSecondary.GetNDF()>0) fKFchi2 = TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF()));
897 // invariant mass of the KF particle
898 kfSecondary.GetMass(fInvmass,fInvmassSigma);
900 // DCA from primary to e-h KF particle (impact parameter of KF particle)
901 Double_t vtx[2]={fPVx, fPVy};
902 fKFip = kfSecondary.GetDistanceFromVertexXY(vtx);
904 if((dx*kfpx+dy*kfpy)>0) fSignedLxy= TMath::Sqrt(dx*dx+dy*dy);
905 if((dx*kfpx+dy*kfpy)<0) fSignedLxy= -1*TMath::Sqrt(dx*dx+dy*dy);
906 //[the other way to think about] - projection of kf vertex vector to the kf momentum direction
907 //Double_t psqr = kfpx*kfpx+kfpy*kfpy;
908 //if(psqr>0) fSignedLxy=(dx*kfpx+dy*kfpy)/TMath::Sqrt(psqr);
910 //recalculating primary vertex after removing secvtx tracks --------------------------
912 trkid[0] = track1->GetID();
913 trkid[1] = track2->GetID();
914 trkid[2] = track3->GetID();
915 trkid[3] = track4->GetID();
917 RecalcPrimvtx(4, trkid, kfTrack);
918 Double_t dx2 = kfx-fPVx2;
919 Double_t dy2 = kfy-fPVy2;
921 // IP of sec particle recalculated based on recalculated primary vertex
922 Double_t vtx2[2]={fPVx2, fPVy2};
923 fKFip2 = kfSecondary.GetDistanceFromVertexXY(vtx2);
924 // signed Lxy recalculated based on recalculated primary vertex
925 if((dx2*kfpx+dy2*kfpy)>0) fSignedLxy2= TMath::Sqrt(dx2*dx2+dy2*dy2);
926 if((dx2*kfpx+dy2*kfpy)<0) fSignedLxy2= -1*TMath::Sqrt(dx2*dx2+dy2*dy2);
927 //------------------------------------------------------------------------------------
931 //_______________________________________________________________________________________________
932 void AliHFEsecVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticle * const kftrk){
934 const AliESDVertex *primvtx = fESD1->GetPrimaryVertex();
936 AliKFVertex kfESDprimary;
937 Int_t n = primvtx->GetNIndices();
942 if (n>0 && primvtx->GetStatus()){
943 kfESDprimary = AliKFVertex(*primvtx);
944 UShort_t *priIndex = primvtx->GetIndices();
945 for(Int_t j=0; j<nkftrk; j++){
946 for (Int_t i=0;i<n;i++){
947 Int_t idx = Int_t(priIndex[i]);
948 if (idx == trkid[j]){
949 kfESDprimary -= kftrk[j];
956 fPVx2 = kfESDprimary.GetX();
957 fPVy2 = kfESDprimary.GetY();
961 //_______________________________________________________________________________________________
962 Int_t AliHFEsecVtx::GetMCPID(AliESDtrack *track)
968 AliMCParticle *mctrack = NULL;
969 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) return 0;
970 TParticle *mcpart = mctrack->Particle();
972 if ( !mcpart ) return 0;
973 Int_t pdgCode = mcpart->GetPdgCode();
978 //_______________________________________________________________________________________________
979 Int_t AliHFEsecVtx::GetPairOriginESD(AliESDtrack* trk1, AliESDtrack* trk2)
982 // return pdg code of the origin(source) of the pair
985 // ---*---*---*-----ancester A----- track1
988 // => if they originated from same ancester,
989 // then return "the absolute value of pdg code of ancester A"
991 // ---*---*---B hadron-----ancester A----- track1
994 // => if they originated from same ancester, and this ancester originally comes from B hadrons
995 // then return -1*"the absolute value of pdg code of ancester A"
997 // caution : it can also return parton pdg code if it originated from same string or gluon spliting.
1000 if (trk1->GetLabel()<0 || trk2->GetLabel()<0) return 0;
1002 AliMCParticle *mctrack = NULL;
1003 AliMCParticle *mctrack1 = NULL;
1004 AliMCParticle *mctrack2 = NULL;
1005 if(!(mctrack1 = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(trk1->GetLabel()))))) return 0;
1006 if(!(mctrack2 = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(trk2->GetLabel()))))) return 0;
1007 TParticle *part1 = mctrack1->Particle();
1008 TParticle *part2 = mctrack2->Particle();
1010 TParticle* part2cp = part2;
1011 if (!(part1) || !(part2)) return 0;
1015 //if the two tracks' mother's label is same, get the mother info
1016 //in case of charm, check if it originated from beauty
1017 for (Int_t i=0; i<10; i++){ //check up to 10 ancesters
1018 Int_t label1 = part1->GetFirstMother();
1019 if (label1 < 0) return 0;
1021 for (Int_t j=0; j<10; j++){ //check up to 10 ancesters
1022 Int_t label2 = part2->GetFirstMother();
1023 if (label2 < 0) break;
1025 if (label1 == label2){ //check if two tracks are originated from same mother
1026 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(label2))))) return 0;
1027 TParticle* commonmom = mctrack->Particle();
1029 srcpdg = abs(commonmom->GetPdgCode());
1031 //check ancester to see if it is originally from beauty
1032 for (Int_t k=0; k<10; k++){ //check up to 10 ancesters
1033 Int_t ancesterlabel = commonmom->GetFirstMother();
1034 if (ancesterlabel < 0) return srcpdg; // if there is no more commonancester, return commonmom's pdg
1036 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(ancesterlabel))))) return 0;
1037 TParticle* commonancester = mctrack->Particle();
1039 Int_t ancesterpdg = abs(commonancester->GetPdgCode());
1041 for (Int_t l=0; l<fNparents; l++){
1042 if (abs(ancesterpdg)==fParentSelect[1][l]){
1043 srcpdg = -1*srcpdg; //multiply -1 for hadron from bottom
1047 commonmom = commonancester;
1050 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(label2))))) return 0;
1051 part2 = mctrack->Particle(); //if their mother is different, go to earlier generation of 2nd particle
1053 if (!(part2)) break;
1055 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(label1))))) return 0;
1056 part1 = mctrack->Particle(); //if their mother is different, go to earlier generation of 1st particle
1058 if (!(part1)) return 0;
1064 //_______________________________________________________________________________________________
1065 Int_t AliHFEsecVtx::GetPairOriginAOD(AliAODTrack* trk1, AliAODTrack* trk2)
1069 // return pdg code of the origin(source) of the pair
1072 // ---*---*---*-----ancester A----- track1
1075 // => if they originated from same ancester,
1076 // then return "the absolute value of pdg code of ancester A"
1078 // ---*---*---B hadron-----ancester A----- track1
1081 // => if they originated from same ancester, and this ancester originally comes from B hadrons
1082 // then return -1*"the absolute value of pdg code of ancester A"
1084 // caution : it can also return parton pdg code if it originated from same string or gluon spliting.
1087 if (trk1->GetLabel()<0 || trk2->GetLabel()<0) return 0;
1088 AliAODMCParticle *part1 = (AliAODMCParticle*)fMCArray->At(trk1->GetLabel());
1089 AliAODMCParticle *part2 = (AliAODMCParticle*)fMCArray->At(trk2->GetLabel());
1090 AliAODMCParticle *part2cp = part2;
1091 if (!(part1) || !(part2)) return 0;
1095 //if the two tracks' mother's label is same, get the mother info
1096 //in case of charm, check if it originated from beauty
1097 for (Int_t i=0; i<10; i++){ //check up to 10 ancesters
1098 Int_t label1 = part1->GetMother();
1099 if (label1 < 0) return 0;
1101 for (Int_t j=0; j<10; j++){ //check up to 10 ancesters
1102 Int_t label2 = part2->GetMother();
1103 if (label2 < 0) return 0;
1105 if (label1 == label2){ //check if two tracks are originated from same mother
1106 AliAODMCParticle *commonmom = (AliAODMCParticle*)fMCArray->At(label1);
1107 srcpdg = abs(commonmom->GetPdgCode());
1109 //check ancester to see if it is originally from beauty
1110 for (Int_t k=0; k<10; k++){ //check up to 10 ancesters
1111 Int_t ancesterlabel = commonmom->GetMother();
1112 if (ancesterlabel < 0) return srcpdg; // if there is no more commonancester, return commonmom's pdg
1114 AliAODMCParticle *commonancester = (AliAODMCParticle*)fMCArray->At(ancesterlabel);
1115 Int_t ancesterpdg = abs(commonancester->GetPdgCode());
1117 for (Int_t l=0; l<fNparents; l++){
1118 if (abs(ancesterpdg)==fParentSelect[1][l]){
1119 srcpdg = -1*srcpdg; //multiply -1 for charm from bottom
1123 commonmom = commonancester;
1126 part2 = (AliAODMCParticle*)fMCArray->At(label2); //if their mother is different, go to earlier generation of 2nd particle
1127 if (!(part2)) break;
1129 part1 = (AliAODMCParticle*)fMCArray->At(label1); //if their mother is different, go to earlier generation of 2nd particle
1131 if (!(part1)) return 0;
1137 //_______________________________________________________________________________________________
1138 Int_t AliHFEsecVtx::GetPairCode(const AliVTrack* const trk1, const AliVTrack* const trk2)
1141 // return pair code which is predefinded as:
1142 // kDirectCharm, kDirectBeauty, kBeautyCharm, kGamma, kPi0,
1143 // kElse, kBeautyGamma, kBeautyPi0, kBeautyElse
1147 Int_t srccode = kElse;
1149 if(IsAODanalysis()) srcpdg = GetPairOriginAOD((AliAODTrack*)trk1,(AliAODTrack*)trk2);
1150 else srcpdg = GetPairOriginESD((AliESDtrack*)trk1,(AliESDtrack*)trk2);
1152 if (srcpdg < 0) srccode = kBeautyElse;
1153 for (Int_t i=0; i<fNparents; i++){
1154 if (abs(srcpdg)==fParentSelect[0][i]) {
1155 if (srcpdg>0) srccode = kDirectCharm;
1156 if (srcpdg<0) srccode = kBeautyCharm;
1158 if (abs(srcpdg)==fParentSelect[1][i]) {
1159 if (srcpdg>0) srccode = kDirectBeauty;
1160 if (srcpdg<0) return kElse;
1163 if (srcpdg == 22) srccode = kGamma;
1164 if (srcpdg == -22) srccode = kBeautyGamma;
1165 if (srcpdg == 111) srccode = kPi0;
1166 if (srcpdg == -111) srccode = kBeautyPi0;
1171 //_______________________________________________________________________________________________
1172 Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack)
1175 // return decay electron's origin
1179 AliDebug(1, "Stack label is negative, return\n");
1183 AliMCParticle *mctrack = NULL;
1184 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(iTrack))))) return -1;
1185 TParticle *mcpart = mctrack->Particle();
1188 AliDebug(1, "no mc particle, return\n");
1192 if ( abs(mcpart->GetPdgCode()) != 11 ) return kMisID;
1194 // if ( abs(mcpart->GetPdgCode()) != 11 ) return -1; // check if it is electron !
1196 Int_t iLabel = mcpart->GetFirstMother();
1198 AliDebug(1, "Stack label is negative, return\n");
1203 Bool_t isFinalOpenCharm = kFALSE;
1205 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return -1;
1206 TParticle *partMother = mctrack->Particle();
1208 Int_t maPdgcode = partMother->GetPdgCode();
1210 // if the mother is charmed hadron
1211 if ( int(abs(maPdgcode)/100.) == kCharm || int(abs(maPdgcode)/1000.) == kCharm ) {
1213 for (Int_t i=0; i<fNparents; i++){
1214 if (abs(maPdgcode)==fParentSelect[0][i]){
1215 isFinalOpenCharm = kTRUE;
1218 if (!isFinalOpenCharm) return -1;
1220 // iterate until you find B hadron as a mother or become top ancester
1221 for (Int_t i=1; i<100; i++){ // check back to the 100 generation older
1223 Int_t jLabel = partMother->GetFirstMother();
1225 origin = kDirectCharm;
1228 if (jLabel < 0){ // safety protection
1229 AliDebug(1, "Stack label is negative, return\n");
1233 // if there is an ancester
1234 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1;
1235 TParticle *grandMa = mctrack->Particle();
1237 Int_t grandMaPDG = grandMa->GetPdgCode();
1239 for (Int_t j=0; j<fNparents; j++){
1240 if (abs(grandMaPDG)==fParentSelect[1][j]){
1241 origin = kBeautyCharm;
1246 partMother = grandMa;
1247 } // end of iteration
1249 else if ( int(abs(maPdgcode)/100.) == kBeauty || int(abs(maPdgcode)/1000.) == kBeauty ) {
1250 for (Int_t i=0; i<fNparents; i++){
1251 if (abs(maPdgcode)==fParentSelect[1][i]){
1252 origin = kDirectBeauty;
1258 //============ gamma ================
1259 else if ( abs(maPdgcode) == 22 ) {
1262 // iterate until you find B hadron as a mother or become top ancester
1263 for (Int_t i=1; i<100; i++){ // check back to the 100 generation older
1265 Int_t jLabel = partMother->GetFirstMother();
1270 if (jLabel < 0){ // safety protection
1271 AliDebug(1, "Stack label is negative, return\n");
1275 // if there is an ancester
1276 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1;
1277 TParticle *grandMa = mctrack->Particle();
1279 Int_t grandMaPDG = grandMa->GetPdgCode();
1281 for (Int_t j=0; j<fNparents; j++){
1282 if (abs(grandMaPDG)==fParentSelect[1][j]){
1283 origin = kBeautyGamma;
1288 partMother = grandMa;
1289 } // end of iteration
1294 //============ pi0 ================
1295 else if ( abs(maPdgcode) == 111 ) {
1298 // iterate until you find B hadron as a mother or become top ancester
1299 for (Int_t i=1; i<100; i++){ // check back to the 100 generation older
1301 Int_t jLabel = partMother->GetFirstMother();
1306 if (jLabel < 0){ // safety protection
1307 AliDebug(1, "Stack label is negative, return\n");
1311 // if there is an ancester
1312 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1;
1313 TParticle *grandMa = mctrack->Particle();
1315 Int_t grandMaPDG = grandMa->GetPdgCode();
1317 for (Int_t j=0; j<fNparents; j++){
1318 if (abs(grandMaPDG)==fParentSelect[1][j]){
1319 origin = kBeautyPi0;
1324 partMother = grandMa;
1325 } // end of iteration
1332 // iterate until you find B hadron as a mother or become top ancester
1333 for (Int_t i=1; i<100; i++){ // check back to the 100 generation older
1335 Int_t jLabel = partMother->GetFirstMother();
1340 if (jLabel < 0){ // safety protection
1341 AliDebug(1, "Stack label is negative, return\n");
1345 // if there is an ancester
1346 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1;
1347 TParticle *grandMa = mctrack->Particle();
1349 Int_t grandMaPDG = grandMa->GetPdgCode();
1351 for (Int_t j=0; j<fNparents; j++){
1352 if (abs(grandMaPDG)==fParentSelect[1][j]){
1353 origin = kBeautyElse;
1358 partMother = grandMa;
1359 } // end of iteration
1365 //_______________________________________________________________________________________________
1366 Int_t AliHFEsecVtx::GetPDG(AliVTrack *track)
1369 // get KF particle input pdg for mass hypothesis
1374 if (fUseMCPID && HasMCData()){
1375 pdgCode = GetMCPDG(track);
1380 GetESDPID((AliESDtrack*)track, pid, prob);
1382 case 0: pdgCode = 11; break;
1383 case 1: pdgCode = 13; break;
1384 case 2: pdgCode = 211; break;
1385 case 3: pdgCode = 321; break;
1386 case 4: pdgCode = 2212; break;
1387 default: pdgCode = -1;
1391 Int_t pid = ((AliAODTrack*)track)->GetMostProbablePID();
1393 case 0: pdgCode = 11; break;
1394 case 1: pdgCode = 13; break;
1395 case 2: pdgCode = 211; break;
1396 case 3: pdgCode = 321; break;
1397 case 4: pdgCode = 2212; break;
1398 default: pdgCode = -1;
1405 //_______________________________________________________________________________________________
1406 Int_t AliHFEsecVtx::GetMCPDG(AliVTrack *track)
1409 // return mc pdg code
1412 Int_t label = TMath::Abs(track->GetLabel());
1414 AliMCParticle *mctrack = NULL;
1416 if (IsAODanalysis()) {
1417 AliAODMCParticle *mcpart = (AliAODMCParticle*)fMCArray->At(label);
1418 if ( !mcpart ) return 0;
1419 pdgCode = mcpart->GetPdgCode();
1422 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(label))))) return 0;
1423 TParticle *mcpart = mctrack->Particle();
1425 if ( !mcpart ) return 0;
1426 pdgCode = mcpart->GetPdgCode();
1432 //______________________________________________________________________________
1433 void AliHFEsecVtx::GetESDPID(AliESDtrack *track, Int_t &recpid, Double_t &recprob)
1436 // calculate likehood for esd pid
1445 Double_t probability[5];
1447 // get probability of the diffenrent particle types
1448 track->GetESDpid(probability);
1450 // find most probable particle in ESD pid
1451 // 0:Electron - 1:Muon - 2:Pion - 3:Kaon - 4:Proton
1452 ipid = TMath::LocMax(5,probability);
1453 max = TMath::MaxElement(5,probability);
1459 //_____________________________________________________________________________
1460 void AliHFEsecVtx::AddHFEpairToArray(const AliHFEpairs* const pair)
1463 // Add a HFE pair to the array
1466 Int_t n = HFEpairs()->GetEntriesFast();
1467 if(n!=fNoOfHFEpairs)AliError(Form("fNoOfHFEpairs != HFEpairs()->GetEntriesFast %i != %i \n", fNoOfHFEpairs, n));
1468 new((*HFEpairs())[n]) AliHFEpairs(*pair);
1471 //_____________________________________________________________________________
1472 TClonesArray *AliHFEsecVtx::HFEpairs()
1475 // Returns the list of HFE pairs
1479 fHFEpairs = new TClonesArray("AliHFEpairs", 200);
1484 //_____________________________________________________________________________
1485 void AliHFEsecVtx::DeleteHFEpairs()
1488 // Delete the list of HFE pairs
1492 fHFEpairs->Delete();
1497 //_____________________________________________________________________________
1498 void AliHFEsecVtx::InitHFEpairs()
1501 // Initialization should be done before make all possible pairs for a given electron candidate
1507 //_____________________________________________________________________________
1508 void AliHFEsecVtx::AddHFEsecvtxToArray(const AliHFEsecVtxs* const secvtx)
1511 // Add a HFE secondary vertex to the array
1514 Int_t n = HFEsecvtxs()->GetEntriesFast();
1515 if(n!=fNoOfHFEsecvtxs)AliError(Form("fNoOfHFEsecvtxs != HFEsecvtxs()->GetEntriesFast %i != %i \n", fNoOfHFEsecvtxs, n));
1516 new((*HFEsecvtxs())[n]) AliHFEsecVtxs(*secvtx);
1519 //_____________________________________________________________________________
1520 TClonesArray *AliHFEsecVtx::HFEsecvtxs()
1523 // Returns the list of HFE secvtx
1527 fHFEsecvtxs = new TClonesArray("AliHFEsecVtxs", 200);
1532 //_____________________________________________________________________________
1533 void AliHFEsecVtx::DeleteHFEsecvtxs()
1536 // Delete the list of HFE pairs
1540 fHFEsecvtxs->Delete();
1541 //delete fHFEsecvtx;
1545 //_____________________________________________________________________________
1546 void AliHFEsecVtx::InitHFEsecvtxs()
1549 // Initialization should be done
1552 fNoOfHFEsecvtxs = 0;
1555 //_______________________________________________________________________________________________
1556 Bool_t AliHFEsecVtx::SingleTrackCut(AliESDtrack* track) const
1558 //if (track->Pt() < 1.0) return kFALSE;
1559 //if (TMath::Abs(track->Eta()) > 0.9) return kFALSE;
1560 //if (!(track->GetStatus() & AliESDtrack::kITSrefit)) return kFALSE;
1561 //if (!(track->GetStatus() & AliESDtrack::kTPCrefit)) return kFALSE;
1562 if (!(TESTBIT(track->GetITSClusterMap(),0))) return kFALSE; // ask hit on the first pixel layer
1563 //if (!(TESTBIT(track->GetITSClusterMap(),0) | TESTBIT(track->GetITSClusterMap(),1))) return kFALSE;
1568 track->GetImpactParameters(dcaR,dcaZ);
1569 if (TMath::Abs(TMath::Sqrt(dcaR*dcaR + dcaZ*dcaZ)) < 0.005) return kFALSE;
1570 if (TMath::Abs(TMath::Sqrt(dcaR*dcaR + dcaZ*dcaZ)) > 0.3) return kFALSE;
1574 //____________________________________________________________
1575 void AliHFEsecVtx::MakeContainer(){
1581 const Int_t nDimPair=6;
1582 Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 13};
1583 //Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 13, 60, 60, 2000, 2000};
1584 const Double_t kInvmassmin = 0., kInvmassmax = 20.;
1585 const Double_t kKFChi2min = 0, kKFChi2max= 50;
1586 const Double_t kOpenanglemin = 0, kOpenanglemax = 3.14;
1587 const Double_t kSignedLxymin = -10, kSignedLxymax= 10;
1588 const Double_t kKFIPmin = -10, kKFIPmax= 10;
1589 const Double_t kPairCodemin = -1, kPairCodemax= 12;
1590 //const Double_t kPtmin = 0, kPtmax= 30;
1591 //const Double_t kDCAsigmin = -5, kDCAsigmax= 5;
1593 Double_t* binEdgesPair[nDimPair];
1594 for(Int_t ivar = 0; ivar < nDimPair; ivar++)
1595 binEdgesPair[ivar] = new Double_t[nBinPair[ivar] + 1];
1597 for(Int_t i=0; i<=nBinPair[0]; i++) binEdgesPair[0][i]=(Double_t)kInvmassmin + (kInvmassmax - kInvmassmin)/nBinPair[0]*(Double_t)i;
1598 for(Int_t i=0; i<=nBinPair[1]; i++) binEdgesPair[1][i]=(Double_t)kKFChi2min + (kKFChi2max - kKFChi2min)/nBinPair[1]*(Double_t)i;
1599 for(Int_t i=0; i<=nBinPair[2]; i++) binEdgesPair[2][i]=(Double_t)kOpenanglemin + (kOpenanglemax - kOpenanglemin)/nBinPair[2]*(Double_t)i;
1600 for(Int_t i=0; i<=nBinPair[3]; i++) binEdgesPair[3][i]=(Double_t)kSignedLxymin + (kSignedLxymax - kSignedLxymin)/nBinPair[3]*(Double_t)i;
1601 for(Int_t i=0; i<=nBinPair[4]; i++) binEdgesPair[4][i]=(Double_t)kKFIPmin + (kKFIPmax - kKFIPmin)/nBinPair[4]*(Double_t)i;
1602 for(Int_t i=0; i<=nBinPair[5]; i++) binEdgesPair[5][i]=(Double_t)kPairCodemin + (kPairCodemax - kPairCodemin)/nBinPair[5]*(Double_t)i;
1603 //for(Int_t i=0; i<=nBinPair[6]; i++) binEdgesPair[6][i]=(Double_t)kPtmin + (kPtmax - kPtmin)/nBinPair[6]*(Double_t)i;
1604 //for(Int_t i=0; i<=nBinPair[7]; i++) binEdgesPair[7][i]=binEdgesPair[6][i];
1605 //for(Int_t i=0; i<=nBinPair[6]; i++) binEdgesPair[6][i]=(Double_t)kDCAsigmin + (kDCAsigmax - kDCAsigmin)/nBinPair[6]*(Double_t)i;
1606 //for(Int_t i=0; i<=nBinPair[7]; i++) binEdgesPair[7][i]=binEdgesPair[6][i];
1608 fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code; dca1; dca2", nDimPair, nBinPair);
1609 //fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code; pt1; pt2; dca1; dca2", nDimPair, nBinPair);
1610 for(Int_t idim = 0; idim < nDimPair; idim++){
1611 fPairQA->SetBinEdges(idim, binEdgesPair[idim]);
1614 fSecVtxList->AddAt(fPairQA,0);
1616 const Int_t nDimSecvtx=9;
1617 Double_t* binEdgesSecvtx[nDimSecvtx];
1618 Int_t nBinSecvtx[nDimSecvtx] = {200, 500, 2000, 2000, 13, 10, 4, 2000, 500};
1619 const Double_t kNtrksmin = 0, kNtrksmax= 10;
1620 const Double_t kTrueBmin = 0, kTrueBmax= 4;
1621 const Double_t kPtmin = 0, kPtmax= 50;
1622 for(Int_t ivar = 0; ivar < nDimSecvtx; ivar++)
1623 binEdgesSecvtx[ivar] = new Double_t[nBinSecvtx[ivar] + 1];
1625 for(Int_t i=0; i<=nBinSecvtx[0]; i++) binEdgesSecvtx[0][i]=binEdgesPair[0][i];
1626 for(Int_t i=0; i<=nBinSecvtx[1]; i++) binEdgesSecvtx[1][i]=binEdgesPair[1][i];
1627 for(Int_t i=0; i<=nBinSecvtx[2]; i++) binEdgesSecvtx[2][i]=binEdgesPair[3][i];
1628 for(Int_t i=0; i<=nBinSecvtx[3]; i++) binEdgesSecvtx[3][i]=binEdgesPair[4][i];
1629 for(Int_t i=0; i<=nBinSecvtx[4]; i++) binEdgesSecvtx[4][i]=binEdgesPair[5][i];
1630 for(Int_t i=0; i<=nBinSecvtx[5]; i++) binEdgesSecvtx[5][i]=(Double_t)kNtrksmin + (kNtrksmax - kNtrksmin)/nBinSecvtx[5]*(Double_t)i;
1631 for(Int_t i=0; i<=nBinSecvtx[6]; i++) binEdgesSecvtx[6][i]=(Double_t)kTrueBmin + (kTrueBmax - kTrueBmin)/nBinSecvtx[6]*(Double_t)i;
1632 for(Int_t i=0; i<=nBinSecvtx[7]; i++) binEdgesSecvtx[7][i]=binEdgesPair[3][i];
1633 for(Int_t i=0; i<=nBinSecvtx[8]; i++) binEdgesSecvtx[8][i]=(Double_t)kPtmin + (kPtmax - kPtmin)/nBinSecvtx[8]*(Double_t)i;
1635 fSecvtxQA = new THnSparseF("secvtxQA", "QA for Secvtx; invmass[GeV/c^2]; KF chi2; signed Lxy; KF ip; pair code; n tracks ", nDimSecvtx, nBinSecvtx);
1636 for(Int_t idim = 0; idim < nDimSecvtx; idim++){
1637 fSecvtxQA->SetBinEdges(idim, binEdgesSecvtx[idim]);
1640 fSecVtxList->AddAt(fSecvtxQA,1);
1642 for(Int_t ivar = 0; ivar < nDimPair; ivar++)
1643 delete binEdgesPair[ivar];
1644 for(Int_t ivar = 0; ivar < nDimSecvtx; ivar++)
1645 delete binEdgesSecvtx[ivar];