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 **************************************************************************/
15 /**************************************************************************
17 * Secondary vertexing construction Class *
20 * MinJung Kweon <minjung@physi.uni-heidelberg.de> *
22 **************************************************************************/
27 #include <TLorentzVector.h>
29 #include <TParticle.h>
31 #include <AliESDEvent.h>
32 #include <AliESDtrack.h>
33 #include "AliHFEsecVtx.h"
34 #include <AliKFParticle.h>
35 #include <AliKFVertex.h>
40 ClassImp(AliHFEsecVtx)
42 //_______________________________________________________________________________________________
43 AliHFEsecVtx::AliHFEsecVtx():
56 // Default constructor
62 //_______________________________________________________________________________________________
63 AliHFEsecVtx::AliHFEsecVtx(const AliHFEsecVtx &p):
67 ,fNparents(p.fNparents)
69 ,fPairTagged(p.fPairTagged)
70 ,fdistTwoSecVtx(p.fdistTwoSecVtx)
72 ,fsignedLxy(p.fsignedLxy)
74 ,finvmassSigma(p.finvmassSigma)
80 //_______________________________________________________________________________________________
82 AliHFEsecVtx::operator=(const AliHFEsecVtx &)
84 // Assignment operator
86 AliInfo("Not yet implemented.");
90 //_______________________________________________________________________________________________
91 AliHFEsecVtx::~AliHFEsecVtx()
95 //cout << "Analysis Done." << endl;
98 //__________________________________________
99 void AliHFEsecVtx::Init()
104 fParentSelect[0][0] = 411;
105 fParentSelect[0][1] = 421;
106 fParentSelect[0][2] = 431;
107 fParentSelect[0][3] = 4122;
108 fParentSelect[0][4] = 4132;
109 fParentSelect[0][5] = 4232;
110 fParentSelect[0][6] = 4332;
112 fParentSelect[1][0] = 511;
113 fParentSelect[1][1] = 521;
114 fParentSelect[1][2] = 531;
115 fParentSelect[1][3] = 5122;
116 fParentSelect[1][4] = 5132;
117 fParentSelect[1][5] = 5232;
118 fParentSelect[1][6] = 5332;
165 //fid[4][3] = {0,1,2, 0,1,3, 0,2,3, 1,2,3};
166 //fia[4][3][2] = {0,1, 0,2, 1,2, 0,1, 0,3, 1,3, 0,2, 0,3, 2,3, 1,2, 1,3, 2,3};
170 //__________________________________________
171 void AliHFEsecVtx::ResetTagVar()
181 //__________________________________________
182 void AliHFEsecVtx::InitAnaPair()
185 for (Int_t i=0; i<20; i++){
186 fpairedTrackID[i] = -1;
188 fpairedInvMass[i] = -1;
189 fpairedSignedLxy[i] = -1;
194 //_______________________________________________________________________________________________
195 void AliHFEsecVtx::CreateHistograms(TString hnopt)
199 fkSourceLabel[fkAll]="all";
200 fkSourceLabel[fkDirectCharm]="directCharm";
201 fkSourceLabel[fkDirectBeauty]="directBeauty";
202 fkSourceLabel[fkBeautyCharm]="beauty2charm";
203 fkSourceLabel[fkGamma]="gamma";
204 fkSourceLabel[fkPi0]="pi0";
205 fkSourceLabel[fkElse]="others";
206 fkSourceLabel[fkBeautyGamma]="beauty22gamma";
207 fkSourceLabel[fkBeautyPi0]="beauty22pi0";
208 fkSourceLabel[fkBeautyElse]="beauty22others";
212 for (Int_t isource = 0; isource < 10; isource++ ){
214 hname=hnopt+"InvMass_"+fkSourceLabel[isource];
215 fHistPair[isource].fInvMass = new TH2F(hname,hname+";invMass;invMassSigma",120,-2,10,100,0,10);
216 hname=hnopt+"InvMassCut1_"+fkSourceLabel[isource];
217 fHistPair[isource].fInvMassCut1 = new TH2F(hname,hname+";invMass;invMassSigma",120,-2,10,100,0,10);
218 hname=hnopt+"InvMassCut2_"+fkSourceLabel[isource];
219 fHistPair[isource].fInvMassCut2 = new TH2F(hname,hname+";invMass;invMassSigma",120,-2,10,100,0,10);
220 hname=hnopt+"KFChi2_"+fkSourceLabel[isource];
221 fHistPair[isource].fKFChi2 = new TH1F(hname,hname,200,0,20);
222 hname=hnopt+"CosOpenAngle_"+fkSourceLabel[isource];
223 fHistPair[isource].fCosOpenAngle = new TH1F(hname,hname,100,-1.1,1.1);
224 hname=hnopt+"SignedLxy_"+fkSourceLabel[isource];
225 fHistPair[isource].fSignedLxy = new TH2F(hname,hname,1000,-5,5,120,-2,10);
226 hname=hnopt+"KFIP_"+fkSourceLabel[isource];
227 fHistPair[isource].fKFIP = new TH1F(hname,hname,1000,-5,5);
231 hname=hnopt+"pt_beautyelec";
232 fHistTagged.fPtBeautyElec= new TH1F(hname,hname,150,0,30);
233 hname=hnopt+"pt_taggedelec";
234 fHistTagged.fPtTaggedElec= new TH1F(hname,hname,150,0,30);
235 hname=hnopt+"pt_righttaggedelec";
236 fHistTagged.fPtRightTaggedElec = new TH1F(hname,hname,150,0,30);
237 hname=hnopt+"pt_wrongtaggedelec";
238 fHistTagged.fPtWrongTaggedElec = new TH1F(hname,hname,150,0,30);
242 //_______________________________________________________________________________________________
243 void AliHFEsecVtx::AnaPair(AliESDtrack* track1, AliESDtrack* track2, Int_t sourcePart, Int_t index2)
246 // get KF particle input pid
247 Int_t pdg1 = GetMCPID(track1);
248 Int_t pdg2 = GetMCPID(track2);
251 // create KF particle of pair
252 AliKFParticle::SetField(fESD1->GetMagneticField());
253 AliKFParticle kfTrack1(*track1, pdg1);
254 AliKFParticle kfTrack2(*track2, pdg2);
256 AliKFParticle kfSecondary(kfTrack1,kfTrack2);
258 // copy primary vertex from ESD
259 AliKFVertex primVtxCopy(*(fESD1->GetPrimaryVertex()));
260 if( primVtxCopy.GetNDF() <1 ) return;
262 //primary vertex point
263 Double_t pvx = primVtxCopy.GetX();
264 Double_t pvy = primVtxCopy.GetY();
265 //Double_t pvz = primVtxCopy.GetZ();
267 //secondary vertex point from kf particle
268 Double_t kfx = kfSecondary.GetX();
269 Double_t kfy = kfSecondary.GetY();
270 //Double_t kfz = kfSecondary.GetZ();
272 //momentum at the decay point from kf particle
273 Double_t kfpx = kfSecondary.GetPx();
274 Double_t kfpy = kfSecondary.GetPy();
275 //Double_t kfpz = kfSecondary.GetPz();
278 Double_t dx = kfx-pvx;
279 Double_t dy = kfy-pvy;
283 // discriminating variables ----------------------------------------------------------
285 // invariant mass of the KF particle
286 Double_t invmass = -1;
287 Double_t invmassSigma = -1;
288 kfSecondary.GetMass(invmass,invmassSigma);
290 // chi2 of the KF particle
291 Double_t kfchi2 = TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF()));
293 // opening angle between two particles in XY plane
294 Double_t cosphi = TMath::Cos(kfTrack1.GetAngleXY(kfTrack2));
296 // projection of kf vertex vector to the kf momentum direction
297 Double_t costheta = ( dx*kfpx + dy*kfpy)/TMath::Sqrt(dx*dx+dy*dy)*TMath::Sqrt(kfpx*kfpx + kfpy*kfpy);
298 Double_t signedLxy = TMath::Sqrt(dx*dx+dy*dy)*costheta;
300 // DCA from primary to e-h KF particle (impact parameter of KF particle)
301 Double_t vtx[2]={pvx, pvy};
302 Double_t kfip = kfSecondary.GetDistanceFromVertexXY(vtx);
308 if( kfchi2 >2. ) return;
311 fHistPair[sourcePart].fInvMass->Fill(invmass,invmassSigma);
312 fHistPair[sourcePart].fKFChi2->Fill(kfchi2);
313 fHistPair[sourcePart].fCosOpenAngle->Fill(cosphi);
314 fHistPair[sourcePart].fSignedLxy->Fill(signedLxy,invmass);
315 fHistPair[sourcePart].fKFIP->Fill(kfip);
317 if ( signedLxy > 0.05 && cosphi > 0.5) {
318 fHistPair[sourcePart].fInvMassCut1->Fill(invmass,invmassSigma);
322 if (signedLxy < 0.05) return;
323 if (cosphi < 0.0) return;
325 // pair tagging if it passed the above cuts
326 fHistPair[sourcePart].fInvMassCut2->Fill(invmass,invmassSigma);
329 // pair tagging condition
330 if ( signedLxy > 0.0 && cosphi > 0) {
331 //if ( signedLxy > 0.06 && cosphi > 0) {
332 fpairedTrackID[fPairTagged] = index2;
333 fpairedChi2[fPairTagged] = kfchi2;
334 fpairedInvMass[fPairTagged] = invmass;
335 fpairedSignedLxy[fPairTagged] = signedLxy;
341 //_______________________________________________________________________________________________
342 void AliHFEsecVtx::RunSECVTX(AliESDtrack *track)
347 if (fPairTagged >= 4) {
348 FindSECVTXCandid4Tracks(track);
350 else if (fPairTagged == 3) {
351 FindSECVTXCandid3Tracks(track);
353 else if (fPairTagged == 2) {
354 FindSECVTXCandid2Tracks(track);
356 else if (fPairTagged == 1) {
361 Int_t imclabel = TMath::Abs(track->GetLabel());
362 if(imclabel<0) return;
363 TParticle* mcpart = fStack->Particle(imclabel);
364 Int_t esource = GetElectronSource(imclabel);
365 if (esource == fkDirectBeauty || esource == fkBeautyCharm || esource == fkBeautyGamma || esource == fkBeautyPi0 || esource == fkBeautyElse){
366 fHistTagged.fPtBeautyElec->Fill(mcpart->Pt());
371 fHistTagged.fPtTaggedElec->Fill(mcpart->Pt());
372 if (esource == fkDirectBeauty || esource == fkBeautyCharm || esource == fkBeautyGamma || esource == fkBeautyPi0 || esource == fkBeautyElse){
373 fHistTagged.fPtRightTaggedElec->Fill(mcpart->Pt());
375 else fHistTagged.fPtWrongTaggedElec->Fill(mcpart->Pt());
380 //_______________________________________________________________________________________________
381 void AliHFEsecVtx::ApplyPairTagCut()
384 if (fpairedChi2[0] > 2.0) return;
385 if (fpairedInvMass[0] < 1.5) return;
386 if (fpairedSignedLxy[0] < 0.5) return;
392 //_______________________________________________________________________________________________
393 Bool_t AliHFEsecVtx::ApplyPairTagCut(Int_t id)
396 if (fpairedChi2[id] > 2.0) return kFALSE;
397 if (fpairedInvMass[id] < 1.5) return kFALSE;
398 if (fpairedSignedLxy[id] < 0.5) return kFALSE;
405 //_______________________________________________________________________________________________
406 Bool_t AliHFEsecVtx::ApplyTagCut(Double_t chi2)
409 if (chi2 > 2.0) return kFALSE;
410 if (finvmass < 1.5) return kFALSE;
411 if (fsignedLxy < 0.5) return kFALSE;
412 if (fcosPhi < 0.90) return kFALSE;
413 if (fdistTwoSecVtx > 0.1) return kFALSE;
419 //_______________________________________________________________________________________________
420 //void AliHFEsecVtx::ApplyTagCut(Double_t chi2, AliESDtrack *track, AliESDtrack *htrack1, AliESDtrack *htrack2)
421 void AliHFEsecVtx::ApplyVtxTagCut(Double_t chi2)
424 if(!ApplyTagCut(chi2)){
425 if(!ApplyPairTagCut(0)) ApplyPairTagCut(1);
430 //_______________________________________________________________________________________________
431 void AliHFEsecVtx::FindSECVTXCandid4Tracks(AliESDtrack *track)
434 // sort pair in increasing order (kFALSE-increasing order)
439 AliESDtrack *htrack[4];
441 TMath::Sort(fPairTagged,fpairedChi2,index,kFALSE);
443 // select 4 partner tracks retruning smallest pair chi2
445 for (Int_t i=0; i<4; i++){
446 htrack[i] = fESD1->GetTrack(fpairedTrackID[index[i]]);
449 // calculated chi2 with 1 electron and 3 partner tracks
450 for (Int_t i=0; i<4; i++){
451 sevchi2[i] = GetSecVtxChi2(track, htrack[fid[i][0]], htrack[fid[i][1]], htrack[fid[i][2]]);
454 // select 3 partner tracks retruning smallest pair chi2
455 // [think] if two smallest chi2 are similar, have to think about better handling of selection
456 TMath::Sort(4,sevchi2,indexA,kFALSE);
458 // calculated chi2 with 1 electron and 2 partner tracks
459 for (Int_t i=0; i<3; i++){
460 sevchi2[i] = GetSecVtxChi2(track, htrack[fia[indexA[0]][i][0]], htrack[fia[indexA[0]][i][1]]);
463 // select 2 partner tracks retruning smallest pair chi2
464 TMath::Sort(3,sevchi2,indexB,kFALSE);
466 // calculate secondary vertex quality variables with 1 electron and 2 hadrons
467 CalcSECVTXProperty(track,htrack[fia[indexA[0]][indexB[0]][0]],htrack[fia[indexA[0]][indexB[0]][1]]);
469 ApplyVtxTagCut(sevchi2[indexB[0]]);
470 //ApplyTagCut(sevchi2[indexB[0]],track,htrack[fia[indexA[0]][indexB[0]][0]],htrack[fia[indexA[0]][indexB[0]][1]]);
474 //_______________________________________________________________________________________________
475 void AliHFEsecVtx::FindSECVTXCandid3Tracks(AliESDtrack *track)
478 // sort pair in increasing order (kFALSE-increasing order)
479 Int_t indexA[1] = { 0 };
482 AliESDtrack *htrack[3];
484 // select 4 partner tracks retruning smallest pair chi2
486 for (Int_t i=0; i<3; i++){
487 htrack[i] = fESD1->GetTrack(fpairedTrackID[i]);
490 // calculated chi2 with 1 electron and 2 partner tracks
491 for (Int_t i=0; i<3; i++){
492 sevchi2[i] = GetSecVtxChi2(track, htrack[fia[indexA[0]][i][0]], htrack[fia[indexA[0]][i][1]]);
495 // select 2 partner tracks retruning smallest pair chi2
496 TMath::Sort(3,sevchi2,indexB,kFALSE);
498 // calculate secondary vertex quality variables with 1 electron and 2 hadrons
499 CalcSECVTXProperty(track,htrack[fia[indexA[0]][indexB[0]][0]],htrack[fia[indexA[0]][indexB[0]][1]]);
501 ApplyVtxTagCut(sevchi2[indexB[0]]);
502 //ApplyTagCut(sevchi2[indexB[0]],track,htrack[fia[indexA[0]][indexB[0]][0]],htrack[fia[indexA[0]][indexB[0]][1]]);
505 //_______________________________________________________________________________________________
506 void AliHFEsecVtx::FindSECVTXCandid2Tracks(AliESDtrack *track)
510 AliESDtrack *htrack[2];
512 for (Int_t i=0; i<2; i++){
513 htrack[i] = fESD1->GetTrack(fpairedTrackID[i]);
516 sevchi2[0] = GetSecVtxChi2(track, htrack[0], htrack[1]);
518 // calculate secondary vertex quality variables with 1 electron and 2 hadrons
519 CalcSECVTXProperty(track,htrack[0],htrack[1]);
521 ApplyVtxTagCut(sevchi2[0]);
522 //ApplyTagCut(sevchi2[0],track,htrack[0],htrack[1]);
525 //_______________________________________________________________________________________________
526 void AliHFEsecVtx::CalcSECVTXProperty(AliESDtrack* track1, AliESDtrack* track2, AliESDtrack* track3)
529 Int_t pdg1 = GetMCPID(track1);
530 Int_t pdg2 = GetMCPID(track2);
531 Int_t pdg3 = GetMCPID(track3);
533 AliKFParticle::SetField(fESD1->GetMagneticField());
534 AliKFParticle kfTrack1(*track1, pdg1);
535 AliKFParticle kfTrack2(*track2, pdg2);
536 AliKFParticle kfTrack3(*track3, pdg3);
538 AliKFParticle kfSecondary12(kfTrack1,kfTrack2);
539 AliKFParticle kfSecondary13(kfTrack1,kfTrack3);
540 AliKFParticle kfSecondary(kfTrack1,kfTrack2,kfTrack3);
542 // copy primary vertex from ESD
543 AliKFVertex primVtxCopy(*(fESD1->GetPrimaryVertex()));
544 //printf("primary ndf= %d\n",primVtxCopy.GetNDF());
545 if( primVtxCopy.GetNDF() <1 ) return;
547 Double_t kdx12 = kfSecondary12.GetX()-primVtxCopy.GetX();
548 Double_t kdy12 = kfSecondary12.GetY()-primVtxCopy.GetY();
549 //Double_t kdz12 = kfSecondary12.GetZ()-primVtxCopy.GetZ();
551 Double_t kdx13 = kfSecondary13.GetX()-primVtxCopy.GetX();
552 Double_t kdy13 = kfSecondary13.GetY()-primVtxCopy.GetY();
553 //Double_t kdz13 = kfSecondary13.GetZ()-primVtxCopy.GetZ();
555 Double_t kdx = kfSecondary.GetX()-primVtxCopy.GetX();
556 Double_t kdy = kfSecondary.GetY()-primVtxCopy.GetY();
557 //Double_t kdz = kfSecondary.GetZ()-primVtxCopy.GetZ();
559 // calculate distance and angle between two secvtxes
560 fdistTwoSecVtx = TMath::Sqrt((kdx12-kdx13)*(kdx12-kdx13) + (kdy12-kdy13)*(kdy12-kdy13));
561 fcosPhi = ( kdx12*kdx13 + kdy12*kdy13 ) / ( TMath::Sqrt(kdx12*kdx12+kdy12*kdy12)*TMath::Sqrt(kdx13*kdx13+kdy13*kdy13) );
562 //Double_t lengthdiff = TMath::Abs(TMath::Sqrt(kdx12*kdx12+kdy12*kdy12) - TMath::Sqrt(kdx13*kdx13+kdy13*kdy13));
564 // calculate angle between secondary vertex vector and secondary particle momentum vector in transverse plane
565 Double_t cosTheta = ( kdx*kfSecondary.GetPx() + kdy*kfSecondary.GetPy()) / TMath::Sqrt(kdx*kdx+kdy*kdy)*TMath::Sqrt(kfSecondary.GetPx()*kfSecondary.GetPx()+kfSecondary.GetPy()*kfSecondary.GetPy());
566 // calculate signed Lxy
567 fsignedLxy = TMath::Sqrt(kdx*kdx+kdy*kdy)*cosTheta;
569 // calculate invariant mass of the kf particle
570 kfSecondary.GetMass(finvmass,finvmassSigma);
573 //_______________________________________________________________________________________________
574 Int_t AliHFEsecVtx::GetMCPID(AliESDtrack *track)
577 Int_t label = TMath::Abs(track->GetLabel());
578 TParticle* mcpart = fStack->Particle(label);
579 if ( !mcpart ) return 0;
580 Int_t pdgCode = mcpart->GetPdgCode();
585 //_______________________________________________________________________________________________
586 Double_t AliHFEsecVtx::GetSecVtxChi2(AliESDtrack* track1, AliESDtrack* track2, AliESDtrack* track3, AliESDtrack* track4)
589 Int_t pdg1 = GetMCPID(track1);
590 Int_t pdg2 = GetMCPID(track2);
591 Int_t pdg3 = GetMCPID(track3);
592 Int_t pdg4 = GetMCPID(track4);
594 AliKFParticle::SetField(fESD1->GetMagneticField());
595 AliKFParticle kfTrack1(*track1, pdg1);
596 AliKFParticle kfTrack2(*track2, pdg2);
597 AliKFParticle kfTrack3(*track3, pdg3);
598 AliKFParticle kfTrack4(*track4, pdg4);
599 AliKFParticle kfSecondary(kfTrack1,kfTrack2,kfTrack3,kfTrack4);
601 return TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF()));
605 //_______________________________________________________________________________________________
606 Double_t AliHFEsecVtx::GetSecVtxChi2(AliESDtrack* track1, AliESDtrack* track2, AliESDtrack* track3)
609 Int_t pdg1 = GetMCPID(track1);
610 Int_t pdg2 = GetMCPID(track2);
611 Int_t pdg3 = GetMCPID(track3);
613 AliKFParticle::SetField(fESD1->GetMagneticField());
614 AliKFParticle kfTrack1(*track1, pdg1);
615 AliKFParticle kfTrack2(*track2, pdg2);
616 AliKFParticle kfTrack3(*track3, pdg3);
617 AliKFParticle kfSecondary(kfTrack1,kfTrack2,kfTrack3);
619 return TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF()));
623 //_______________________________________________________________________________________________
624 Double_t AliHFEsecVtx::GetSecVtxChi2(AliESDtrack* track1, AliESDtrack* track2)
627 Int_t pdg1 = GetMCPID(track1);
628 Int_t pdg2 = GetMCPID(track2);
630 AliKFParticle::SetField(fESD1->GetMagneticField());
631 AliKFParticle kfTrack1(*track1, pdg1);
632 AliKFParticle kfTrack2(*track2, pdg2);
633 AliKFParticle kfSecondary(kfTrack1,kfTrack2);
635 return TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF()));
639 //_______________________________________________________________________________________________
640 Int_t AliHFEsecVtx::PairOrigin(AliESDtrack* track1, AliESDtrack* track2)
644 // return pdg code of the origin(source) of the pair
647 // ---*---*---*-----ancester A----- track1
650 // => if they originated from same ancester,
651 // then return "the absolute value of pdg code of ancester A"
653 // ---*---*---B hadron-----ancester A----- track1
656 // => if they originated from same ancester, and this ancester originally comes from B hadrons
657 // then return -1*"the absolute value of pdg code of ancester A"
659 // caution : it can also return parton pdg code if it originated from same string or gluon spliting.
662 TParticle* part1 = fStack->Particle(TMath::Abs(track1->GetLabel()));
663 TParticle* part2 = fStack->Particle(TMath::Abs(track2->GetLabel()));
664 if (!(part1)) return 0;
665 if (!(part2)) return 0;
667 TParticle* part1Crtgen = part1; // copy track into current generation particle
668 TParticle* part2Crtgen = part2; // copy track into current generation particle
673 // if the two tracks' mother's label is same, get the mother info
674 // in case of charm, check if it originated from beauty
675 for (Int_t i=0; i<100; i++){ // iterate 100
676 Int_t iLabel = part1Crtgen->GetFirstMother(); //label of mother of current generation for 1st partilce
677 if (iLabel < 0) return 0;
679 for (Int_t j=0; j<100; j++){ // iterate 100
680 Int_t jLabel = part2Crtgen->GetFirstMother(); //label of mother of current generation for 2nd partilce
681 if (jLabel < 0) return 0; // if jLabel == -1
683 if (iLabel == jLabel){ // check if two tracks are originated from same mother
684 TParticle* thismother = fStack->Particle(jLabel); // if yes, get "thismother" info
685 sourcePDG = abs(thismother->GetPdgCode()); // get the pdg code of "this mother"
687 // check ancester to see if it is originally from beauty
688 for (Int_t k=0; k<10; k++){ // check up to 10 ancesters
689 Int_t ancesterLabel = thismother->GetFirstMother();
690 if (ancesterLabel < 0) return sourcePDG; // if "thismoter" doesn't have mother anymore, return thismother's pdg
692 TParticle* thisancester = fStack->Particle(ancesterLabel);
693 Int_t ancesterPDG = abs(thisancester->GetPdgCode());
695 for (Int_t l=0; l<fNparents; l++){
696 if (abs(ancesterPDG)==fParentSelect[1][l]){
697 sourcePDG = -1*sourcePDG; // multiply -1 for charm from bottom
701 thismother = thisancester;
705 part2Crtgen = fStack->Particle(jLabel); // if their mother is different, go up to previous generation of 2nd particle
707 part1Crtgen = fStack->Particle(iLabel); // if their mother is different, go up to previous generation of 2nd particle
709 // if you don't find additionional(2nd particle) track originated from a given beauty hadron, break to save time
710 Int_t motherPDGtmp = abs(part1Crtgen->GetPdgCode());
711 for (Int_t l=0; l<fNparents; l++){
712 if (abs(motherPDGtmp)==fParentSelect[1][l]) return sourcePDG;
721 //_______________________________________________________________________________________________
722 Int_t AliHFEsecVtx::PairCode(AliESDtrack* track1,AliESDtrack* track2)
726 // return pair code which is predefind as:
727 // fkDirectCharm, fkDirectBeauty, fkBeautyCharm, fkGamma, fkPi0, fkElse, fkBeautyGamma, fkBeautyPi0, fkBeautyElse
730 Int_t pairOriginsPDG = PairOrigin(track1,track2);
732 Int_t sourcePart = fkElse;
734 if (pairOriginsPDG < 0) {
735 sourcePart = fkBeautyElse;
737 for (Int_t i=0; i<fNparents; i++){
738 if (abs(pairOriginsPDG)==fParentSelect[0][i]) {
739 if (pairOriginsPDG>0) sourcePart = fkDirectCharm;
740 if (pairOriginsPDG<0) {
741 sourcePart = fkBeautyCharm;
744 if (abs(pairOriginsPDG)==fParentSelect[1][i]) {
745 if (pairOriginsPDG>0) {
746 sourcePart = fkDirectBeauty;
748 if (pairOriginsPDG<0) return fkElse;
751 if (pairOriginsPDG == 22) sourcePart = fkGamma;
752 if (pairOriginsPDG == -22) {
753 sourcePart = fkBeautyGamma;
755 if (pairOriginsPDG == 111) sourcePart = fkPi0;
756 if (pairOriginsPDG == -111) {
757 sourcePart = fkBeautyPi0;
764 //_______________________________________________________________________________________________
765 Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrackLabel)
769 // decay electron's origin
772 if (iTrackLabel < 0) {
773 AliDebug(1, "Stack label is negative, return\n");
777 TParticle* mcpart = fStack->Particle(iTrackLabel);
778 Int_t iLabel = mcpart->GetFirstMother();
780 AliDebug(1, "Stack label is negative, return\n");
785 Bool_t IsFinalOpenCharm = kFALSE;
787 TParticle *partMother = fStack->Particle(iLabel);
788 Int_t maPdgcode = partMother->GetPdgCode(); // get mother's pdg code
790 //beauty --------------------------
791 if ( int(abs(maPdgcode)/100.) == fkBeauty || int(abs(maPdgcode)/1000.) == fkBeauty ) {
792 for (Int_t i=0; i<fNparents; i++){
793 if (abs(maPdgcode)==fParentSelect[1][i]){
794 origin = fkDirectBeauty;
797 else return -1; // this track is originated beauties not in the final B hadron list => excited beauties
801 //charm --------------------------
802 else if ( int(abs(maPdgcode)/100.) == fkCharm || int(abs(maPdgcode)/1000.) == fkCharm ) {
804 for (Int_t i=0; i<fNparents; i++){
805 if (abs(maPdgcode)==fParentSelect[0][i])
806 IsFinalOpenCharm = kTRUE;
808 if (!IsFinalOpenCharm) return -1; // this track is originated charms not in the final D hadron list => excited charms
809 // to prevent any possible double counting
811 for (Int_t i=0; i<100; i++){ // iterate 100 until you find B hadron as a mother or become top ancester
813 Int_t jLabel = partMother->GetFirstMother();
815 origin = fkDirectCharm;
818 if (jLabel < 0){ // safety protection even though not really necessary here
819 AliDebug(1, "Stack label is negative, return\n");
823 // if there is an ancester, check if it in the final B hadron list
824 TParticle* grandMa = fStack->Particle(jLabel);
825 Int_t grandMaPDG = grandMa->GetPdgCode();
827 for (Int_t j=0; j<fNparents; j++){
828 if (abs(grandMaPDG)==fParentSelect[1][j]){
829 origin = fkBeautyCharm;
834 partMother = grandMa;
835 } // end of iteration
838 //gamma --------------------------
839 else if ( abs(maPdgcode) == 22 ) {
842 // iterate until you find B hadron as a mother or become top ancester
843 for (Int_t i=0; i<100; i++){ // check back to the 100 generation older
845 Int_t jLabel = partMother->GetFirstMother();
850 if (jLabel < 0){ // safety protection
851 AliDebug(1, "Stack label is negative, return\n");
855 // if there is an ancester
856 TParticle* grandMa = fStack->Particle(jLabel);
857 Int_t grandMaPDG = grandMa->GetPdgCode();
859 for (Int_t j=0; j<fNparents; j++){
860 if (abs(grandMaPDG)==fParentSelect[1][j]){
861 origin = fkBeautyGamma;
866 partMother = grandMa;
867 } // end of iteration
872 //pi0 --------------------------
873 else if ( abs(maPdgcode) == 111 ) {
876 // iterate until you find B hadron as a mother or become top ancester
877 for (Int_t i=0; i<100; i++){ // check back to the 100 generation older
879 Int_t jLabel = partMother->GetFirstMother();
884 if (jLabel < 0){ // safety protection
885 AliDebug(1, "Stack label is negative, return\n");
889 // if there is an ancester
890 TParticle* grandMa = fStack->Particle(jLabel);
891 Int_t grandMaPDG = grandMa->GetPdgCode();
893 for (Int_t j=0; j<fNparents; j++){
894 if (abs(grandMaPDG)==fParentSelect[1][j]){
895 origin = fkBeautyPi0;
900 partMother = grandMa;
901 } // end of iteration
907 //else --------------------------
911 // iterate until you find B hadron as a mother or become top ancester
912 for (Int_t i=0; i<100; i++){ // check back to the 100 generation older
914 Int_t jLabel = partMother->GetFirstMother();
919 if (jLabel < 0){ // safety protection
920 AliDebug(1, "Stack label is negative, return\n");
924 // if there is an ancester
925 TParticle* grandMa = fStack->Particle(jLabel);
926 Int_t grandMaPDG = grandMa->GetPdgCode();
928 for (Int_t j=0; j<fNparents; j++){
929 if (abs(grandMaPDG)==fParentSelect[1][j]){
930 origin = fkBeautyElse;
935 partMother = grandMa;
936 } // end of iteration
944 //_______________________________________________________________________________________________
945 Bool_t AliHFEsecVtx::SingleTrackCut(AliESDtrack* track)
948 //if (track->Pt() < 1.0) return kFALSE;
949 //if (TMath::Abs(track->Eta()) > 0.9) return kFALSE;
950 //if (!(track->GetStatus() & AliESDtrack::kITSrefit)) return kFALSE;
951 //if (!(track->GetStatus() & AliESDtrack::kTPCrefit)) return kFALSE;
952 if (!(TESTBIT(track->GetITSClusterMap(),0))) return kFALSE; // ask hit on the first pixel layer
953 //if (!(TESTBIT(track->GetITSClusterMap(),0) | TESTBIT(track->GetITSClusterMap(),1))) return kFALSE;
959 track->GetImpactParameters(dcaR,dcaZ);
960 if (TMath::Abs(TMath::Sqrt(dcaR*dcaR + dcaZ*dcaZ)) < 0.005) return kFALSE;
961 if (TMath::Abs(TMath::Sqrt(dcaR*dcaR + dcaZ*dcaZ)) > 0.3) return kFALSE;