1 /**************************************************************************
2 * Copyright(c) 2007-2011, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////
20 // Class to compute variables for correction framework //
21 // for 3-body decays of D mesons (D+, Ds, Lc) //
22 // in bins of cut variables //
23 // Origin: Francesco Prino (prino@to.infn.it) //
24 // Renu Bala (bala@to.infn.it) //
25 // Davide Caffarri (cafarri@pd.infn.it) //
26 ///////////////////////////////////////////////////////////////////
28 #include "AliAODMCParticle.h"
29 #include "AliAODEvent.h"
30 #include "TClonesArray.h"
31 #include "AliCFVertexingHF.h"
32 #include "AliESDtrack.h"
33 #include "TDatabasePDG.h"
35 #include "AliCFVertexingHF3Prong.h"
36 #include "AliCFContainer.h"
38 ClassImp(AliCFVertexingHF3Prong)
41 //_________________________________________
42 AliCFVertexingHF3Prong::AliCFVertexingHF3Prong(Int_t decay):
49 fPtAccCut=new Float_t[fProngs];
50 fEtaAccCut=new Float_t[fProngs];
51 for(Int_t iP=0; iP<fProngs; iP++){
57 //_________________________________________
58 AliCFVertexingHF3Prong::AliCFVertexingHF3Prong(TClonesArray *mcArray, UShort_t originDselection, Int_t decay):
59 AliCFVertexingHF(mcArray, originDselection),
65 fPtAccCut=new Float_t[fProngs];
66 fEtaAccCut=new Float_t[fProngs];
67 for(Int_t iP=0; iP<fProngs; iP++){
74 //_____________________________________
75 AliCFVertexingHF3Prong& AliCFVertexingHF3Prong::operator=(const AliCFVertexingHF3Prong& c){
79 AliCFVertexingHF::operator=(c);
85 //__________________________________________
86 Bool_t AliCFVertexingHF3Prong::SetRecoCandidateParam(AliAODRecoDecayHF *recoCand){
87 // Checks if candidate is signal and D meson is present in MC array
89 Bool_t bSignAssoc = kFALSE;
90 fRecoCandidate = recoCand;
92 if (!fRecoCandidate) {
93 AliError("fRecoCandidate not found, problem in assignement\n");
98 Int_t pdgDaughter[3]={-1,-1,-1};
99 if(fDecay==kDplustoKpipi){
104 }else if(fDecay==kDstoKKpi){
109 }else if(fDecay==kLctopKpi){
115 AliError("WRONG DECAY SETTING");
119 Int_t mcLabel = fRecoCandidate->MatchToMC(pdgCand,fmcArray,3,pdgDaughter);
120 if (mcLabel == -1) return bSignAssoc;
122 if (fRecoCandidate->NumberOfFakeDaughters()>0){
123 fFake = 0; // fake candidate
124 if (fFakeSelection==1) return bSignAssoc;
126 if (fRecoCandidate->NumberOfFakeDaughters()==0){
127 fFake = 2; // non-fake candidate
128 if (fFakeSelection==2) return bSignAssoc;
132 fmcPartCandidate = dynamic_cast<AliAODMCParticle*>(fmcArray->At(fmcLabel));
134 if (!fmcPartCandidate){
135 AliDebug(3,"No part candidate");
143 //______________________________________________
144 Bool_t AliCFVertexingHF3Prong::GetGeneratedValuesFromMCParticle(Double_t* vectorMC) {
146 // collecting all the necessary info from MC particle and fill vectorMC: 12 variables
161 Bool_t bGenValues = kFALSE;
164 if(fDecay==kDplustoKpipi){
166 }else if(fDecay==kDstoKKpi){
168 }else if(fDecay==kLctopKpi){
171 AliError("WRONG DECAY SETTING");
175 Double_t vertD[3] = {0,0,0}; // D origin
176 fmcPartCandidate->XvYvZv(vertD); // cm
180 Short_t charge = fmcPartCandidate->Charge();
182 // order the daughters as LS,OS,LS, e.g. D+ -> pi+ K- pi+
183 // the 2 LS are ordered so that in pos. 0 there is the one with lower label value
189 Int_t nDau=fmcPartCandidate->GetNDaughters();
190 Int_t labelFirstDau = fmcPartCandidate->GetDaughter(0);
192 for(Int_t iDau=0; iDau<3; iDau++){
193 Int_t ind = labelFirstDau+iDau;
194 AliAODMCParticle* part = dynamic_cast<AliAODMCParticle*>(fmcArray->At(ind));
196 AliError("Daughter particle not found in MC array");
199 Short_t signDau=part->Charge();
202 daughter[index] = ind;
210 for(Int_t iDau=0; iDau<2; iDau++){
211 Int_t ind = labelFirstDau+iDau;
212 AliAODMCParticle* part = dynamic_cast<AliAODMCParticle*>(fmcArray->At(ind));
214 AliError("Daughter particle not found in MC array");
217 Int_t pdgCode=TMath::Abs(part->GetPdgCode());
218 if(pdgCode==211 || pdgCode==321 || pdgCode==2212){
219 Short_t signDau=part->Charge();
222 daughter[index] = ind;
229 Int_t nDauRes=part->GetNDaughters();
231 AliError("Wrong resonant decay");
234 Int_t labelFirstDauRes = part->GetDaughter(0);
235 for(Int_t iDauRes=0; iDauRes<2; iDauRes++){
236 Int_t indDR = labelFirstDauRes+iDauRes;
237 AliAODMCParticle* partDR = dynamic_cast<AliAODMCParticle*>(fmcArray->At(indDR));
239 AliError("Daughter particle not found in MC array");
242 Short_t signDau=partDR->Charge();
245 daughter[index] = ind;
255 AliError(Form("Wrong number of daughters %d",nDau));
259 if(nDauLS!=2 || nDauOS!=1){
260 AliError(Form("Wrong decay channel: LS and OS daughters not OK: %d %d",nDauLS,nDauOS));
263 if(daughter[0]>daughter[2]){
264 Int_t tmp=daughter[0];
265 daughter[0]=daughter[2];
269 // getting the momentum from the daughters and decay vertex
270 Double_t px[3],py[3],pz[3],pt[3];
271 Double_t vertDec[3] = {0,0,0}; // decay vertex
272 for(Int_t iDau=0; iDau<3; iDau++){
273 AliAODMCParticle* part=dynamic_cast<AliAODMCParticle*>(fmcArray->At(daughter[iDau]));
275 AliError("Daughter particle not found in MC array");
282 if(iDau==0) part->XvYvZv(vertDec);
285 Double_t d0[3] = {0.,0.,0.}; // dummy values!!!!
287 AliAODRecoDecayHF* decay = new AliAODRecoDecayHF(vertD,vertDec,nprongs,charge,px,py,pz,d0);
288 Double_t cT = decay->Ct(pdgCand);
290 vectorMC[0] = fmcPartCandidate->Pt();
291 vectorMC[1] = fmcPartCandidate->Y() ;
292 vectorMC[2] = fmcPartCandidate->Phi();
293 vectorMC[3] = cT*1.E4 ; // in micron
294 vectorMC[4] = 1.01; // cos pointing angle, dummy value, meaningless in MC
298 vectorMC[8] = 0.; // imppar0, dummy value, meaningless in MC
299 vectorMC[9] = 0.; // imppar1, dummy value, meaningless in MC, in micron
300 vectorMC[10] = 0.; // imppar2, dummy value, meaningless in MC, in micron
301 vectorMC[11] = fzMCVertex; // z of reconstructed of primary vertex
302 vectorMC[12] = fCentValue; // reconstructed centrality value
303 vectorMC[13] = 1.; // always filling with 1 at MC level
305 if (fDecay==kLctopKpi){
318 //____________________________________________
319 Bool_t AliCFVertexingHF3Prong::GetRecoValuesFromCandidate(Double_t *vectorReco) const
321 // Fill vector (see above) with reconstructed quantities
322 Bool_t bFillRecoValues=kFALSE;
325 if(fDecay==kDplustoKpipi){
327 }else if(fDecay==kDstoKKpi){
329 }else if(fDecay==kLctopKpi){
331 // AliError("LambdaC not yet implemented");
332 // return bFillRecoValues;
334 AliError("WRONG DECAY SETTING");
335 return bFillRecoValues;
338 AliAODRecoDecayHF3Prong *decay3 = (AliAODRecoDecayHF3Prong*)fRecoCandidate;
339 Short_t charge=decay3->Charge();
340 Double_t rapidity=decay3->Y(pdgCand);
341 Double_t cT=decay3->Ct(pdgCand);
342 Double_t pt = decay3->Pt();
343 Double_t cosPointingAngle = decay3->CosPointingAngle();
344 Double_t phi = decay3->Phi();
345 Double_t dist12= decay3->GetDist12toPrim();
346 Double_t dist23 = decay3->GetDist23toPrim();
347 Double_t sigmVert = decay3->GetSigmaVert();
350 Int_t daughtSorted[3];
354 for(Int_t iDau=0; iDau<3; iDau++){
355 AliAODTrack *trk = (AliAODTrack*)decay3->GetDaughter(iDau);
356 Int_t label = TMath::Abs(trk->GetLabel());
357 Short_t chargedau=trk->Charge();
358 if(chargedau==charge){
359 daughtSorted[tmpIndex]=label;
363 daughtSorted[1]=label;
368 if(nDauLS!=2 || nDauOS!=1){
369 AliError("Wrong decay channel: number of OS and LS tracks not OK");
370 return bFillRecoValues;
373 if(daughtSorted[0]>daughtSorted[2]){
374 Int_t tmp=daughtSorted[0];
375 daughtSorted[0]=daughtSorted[2];
379 Double_t d0prong0 = decay3->Getd0Prong(daughtSorted[0]);
380 Double_t d0prong1 = decay3->Getd0Prong(daughtSorted[1]);
381 Double_t d0prong2 = decay3->Getd0Prong(daughtSorted[2]);
384 vectorReco[1] = rapidity;
386 vectorReco[3] = cT*1.E4; // in micron
387 vectorReco[4] = cosPointingAngle; // in micron
388 vectorReco[5] = decay3->PtProng(daughtSorted[0]);
389 vectorReco[6] = decay3->PtProng(daughtSorted[1]);
390 vectorReco[7] = decay3->PtProng(daughtSorted[2]);
391 vectorReco[8] = decay3->Getd0Prong(daughtSorted[0]);
392 vectorReco[9] = decay3->Getd0Prong(daughtSorted[1]);
393 vectorReco[10] = decay3->Getd0Prong(daughtSorted[2]);
394 vectorReco[11] = fzPrimVertex; // z of reconstructed of primary vertex
395 vectorReco[12] = fCentValue; //reconstructed centrality value
396 vectorReco[13] = fFake; // whether the reconstructed candidate was a fake (fFake = 0) or not (fFake = 2)
398 if(fDecay==kLctopKpi){
399 Double_t sumd02 =(d0prong0*d0prong0 + d0prong1*d0prong1 + d0prong2*d0prong2);
400 vectorReco[14] = dist12*1.E4;
401 vectorReco[15] = dist23*1.E4;
402 vectorReco[16] = sigmVert*1.E4;
403 vectorReco[17] = sumd02*1.E8;
407 bFillRecoValues = kTRUE;
408 return bFillRecoValues;
412 //_____________________________________________________________
413 Bool_t AliCFVertexingHF3Prong::CheckMCChannelDecay() const
415 // Check the pdg codes of the daughters
416 Bool_t checkCD = kFALSE;
419 Int_t pdgDaughter[3]={-1,-1,-1};
420 if(fDecay==kDplustoKpipi){
425 }else if(fDecay==kDstoKKpi){
430 }else if(fDecay==kLctopKpi){
436 // AliError("LambdaC not yet implemented");
439 AliError("WRONG DECAY SETTING");
446 Int_t nDau=fmcPartCandidate->GetNDaughters();
447 Int_t labelFirstDau = fmcPartCandidate->GetDaughter(0);
449 for(Int_t iDau=0; iDau<3; iDau++){
450 Int_t ind = labelFirstDau+iDau;
451 AliAODMCParticle* part = dynamic_cast<AliAODMCParticle*>(fmcArray->At(ind));
453 AliError("Daughter particle not found in MC array");
456 daughter[iDau]=TMath::Abs(part->GetPdgCode());
460 for(Int_t iDau=0; iDau<2; iDau++){
461 Int_t ind = labelFirstDau+iDau;
462 AliAODMCParticle* part = dynamic_cast<AliAODMCParticle*>(fmcArray->At(ind));
464 AliError("Daughter particle not found in MC array");
467 Int_t pdgCode=TMath::Abs(part->GetPdgCode());
468 if(pdgCode==211 || pdgCode==321 || pdgCode==2212){
469 if(nDauFound>=3) return checkCD;
470 daughter[nDauFound]=pdgCode;
473 Int_t nDauRes=part->GetNDaughters();
474 if(nDauRes!=2) return checkCD;
475 Int_t labelFirstDauRes = part->GetDaughter(0);
476 for(Int_t iDauRes=0; iDauRes<2; iDauRes++){
477 Int_t indDR = labelFirstDauRes+iDauRes;
478 AliAODMCParticle* partDR = dynamic_cast<AliAODMCParticle*>(fmcArray->At(indDR));
480 AliError("Daughter particle not found in MC array");
483 Int_t pdgCodeDR=TMath::Abs(partDR->GetPdgCode());
484 if(nDauFound>=3) return checkCD;
485 daughter[nDauFound]=pdgCodeDR;
493 for(Int_t iDau1=0; iDau1<3; iDau1++){
494 for(Int_t iDau2=iDau1; iDau2<3; iDau2++){
495 if(daughter[iDau1]<daughter[iDau2]){
496 Int_t tmp=daughter[iDau1];
497 daughter[iDau1]=daughter[iDau2];
502 for(Int_t iDau=0; iDau<3; iDau++){
503 if(daughter[iDau]!=pdgDaughter[iDau]){
504 AliDebug(2, "Wrong decay channel from MC, skipping!!");