1 /**************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 //-----------------------------------------------------------------------
19 // Class for HF corrections as a function of many variables and step
20 // Author : C. Zampolli, CERN
21 // D. Caffarri, Univ & INFN Padova caffarri@pd.infn.it
22 // Base class for HF Unfolding - agrelli@uu.nl
23 //-----------------------------------------------------------------------
25 #include "TParticle.h"
26 #include "TClonesArray.h"
27 #include "AliAODMCParticle.h"
28 #include "AliAODRecoDecayHF.h"
29 #include "AliAODRecoDecayHF2Prong.h"
30 #include "AliAODRecoDecayHF3Prong.h"
31 #include "AliAODRecoDecayHF4Prong.h"
32 #include "AliAODRecoCascadeHF.h"
33 #include "AliAODMCHeader.h"
34 #include "AliAODEvent.h"
36 #include "AliESDtrackCuts.h"
37 #include "AliESDtrack.h"
38 #include "AliCFTaskVertexingHF.h"
40 #include "AliCFVertexingHF.h"
42 //___________________________________________________________
43 AliCFVertexingHF::AliCFVertexingHF() :
46 fmcPartCandidate(0x0),
51 fFillFromGenerated(0),
54 fKeepDfromBOnly(kFALSE),
62 fFake(1.), // setting to MC value
63 fRejectIfNoQuark(kFALSE),
65 fConfiguration(AliCFTaskVertexingHF::kCheetah) // by default, setting the fast configuration
77 //_____________________________________________________
78 AliCFVertexingHF::AliCFVertexingHF(TClonesArray *mcArray, UShort_t originDselection) :
81 fmcPartCandidate(0x0),
86 fFillFromGenerated(0),
89 fKeepDfromBOnly(kFALSE),
97 fFake(1.), // setting to MC value
98 fRejectIfNoQuark(kFALSE),
100 fConfiguration(AliCFTaskVertexingHF::kCheetah) // by default, setting the fast configuration
103 // constructor with mcArray
106 SetDselection(originDselection);
110 //_______________________________________________________
111 AliCFVertexingHF::~AliCFVertexingHF()
117 if (fmcArray) fmcArray = 0x0;
118 if (fRecoCandidate) fRecoCandidate = 0x0;
119 if (fmcPartCandidate) fmcPartCandidate = 0x0;
121 delete [] fLabelArray;
129 delete [] fEtaAccCut;
134 //_____________________________________________________
135 AliCFVertexingHF& AliCFVertexingHF::operator=(const AliCFVertexingHF& c)
138 // assigment operator
142 TObject::operator=(c);
144 fmcArray = new TClonesArray(*(c.fmcArray));
145 delete fRecoCandidate;
146 fRecoCandidate = new AliAODRecoDecayHF(*(c.fRecoCandidate));
147 delete fmcPartCandidate;
148 fmcPartCandidate = new AliAODMCParticle(*(c.fmcPartCandidate));
149 fNDaughters = c.fNDaughters;
151 fzPrimVertex = c.fzPrimVertex;
152 fzMCVertex = c.fzMCVertex;
153 fFillFromGenerated = c.fFillFromGenerated;
154 fOriginDselection = c.fOriginDselection;
155 fKeepDfromB = c.fKeepDfromB;
156 fKeepDfromBOnly = c.fKeepDfromBOnly;
157 fmcLabel = c.fmcLabel;
159 fCentValue=c.fCentValue;
160 fFakeSelection=c.fFakeSelection;
162 fRejectIfNoQuark=c.fRejectIfNoQuark;
164 delete [] fLabelArray;
166 delete [] fEtaAccCut;
167 fLabelArray = new Int_t[fProngs];
168 fPtAccCut = new Float_t[fProngs];
169 fEtaAccCut = new Float_t[fProngs];
170 for(Int_t iP=0; iP<fProngs; iP++){
171 fLabelArray[iP]=c.fLabelArray[iP];
172 fPtAccCut[iP]=c.fPtAccCut[iP];
173 fEtaAccCut[iP]=c.fEtaAccCut[iP];
176 fMultiplicity=c.fMultiplicity;
177 fConfiguration=c.fConfiguration;
183 //____________________________________________________
184 AliCFVertexingHF::AliCFVertexingHF(const AliCFVertexingHF &c) :
189 fNDaughters(c.fNDaughters),
191 fzPrimVertex(c.fzPrimVertex),
192 fzMCVertex(c.fzMCVertex),
193 fFillFromGenerated(c.fFillFromGenerated),
194 fOriginDselection (c.fOriginDselection),
195 fKeepDfromB (c.fKeepDfromB),
196 fKeepDfromBOnly (c.fKeepDfromBOnly),
197 fmcLabel(c.fmcLabel),
200 fCentValue(c.fCentValue),
203 fFakeSelection(c.fFakeSelection),
205 fRejectIfNoQuark(c.fRejectIfNoQuark),
206 fMultiplicity(c.fMultiplicity),
207 fConfiguration(c.fConfiguration)
212 fmcArray = new TClonesArray(*(c.fmcArray));
213 fRecoCandidate = new AliAODRecoDecayHF(*(c.fRecoCandidate));
214 fmcPartCandidate = new AliAODMCParticle(*(c.fmcPartCandidate));
216 fLabelArray = new Int_t[fProngs];
217 fPtAccCut = new Float_t[fProngs];
218 fEtaAccCut = new Float_t[fProngs];
219 if (c.fLabelArray) memcpy(fLabelArray,c.fLabelArray,fProngs*sizeof(Int_t));
220 if (c.fPtAccCut) memcpy(fPtAccCut,c.fPtAccCut,fProngs*sizeof(Int_t));
221 if (c.fEtaAccCut) memcpy(fEtaAccCut,c.fEtaAccCut,fProngs*sizeof(Int_t));
225 //___________________________________________________________
226 void AliCFVertexingHF::SetDselection(UShort_t originDselection)
228 // setting the way the D0 will be selected
229 // 0 --> only from c quarks
230 // 1 --> only from b quarks
231 // 2 --> from both c quarks and b quarks
233 fOriginDselection = originDselection;
235 if (fOriginDselection == 0) {
236 fKeepDfromB = kFALSE;
237 fKeepDfromBOnly = kFALSE;
240 if (fOriginDselection == 1) {
242 fKeepDfromBOnly = kTRUE;
245 if (fOriginDselection == 2) {
247 fKeepDfromBOnly = kFALSE;
253 //______________________________________________________
254 void AliCFVertexingHF::SetMCCandidateParam(Int_t label)
257 // setting the parameters (candidate and n. daughters)
260 fmcPartCandidate = dynamic_cast <AliAODMCParticle*> (fmcArray->At(label));
261 if (fmcPartCandidate){
262 fNDaughters = fmcPartCandidate->GetNDaughters();
265 AliError(Form("Dynamic cast failed, fNdaughters will remain set to %d",fNDaughters));
270 //____________________________________________________________
271 Int_t AliCFVertexingHF::MCcquarkCounting(AliAODMCParticle* mcPart) const
274 // counting the c-quarks
279 if (mcPart->GetPdgCode() == 4) cquarks++;
280 if (mcPart->GetPdgCode() == -4) cquarks++;
283 AliWarning("Particle not found in tree, skipping\n");
290 //________________________________________________________
291 Bool_t AliCFVertexingHF::CheckMCPartFamily(AliAODMCParticle */*mcPart*/, TClonesArray */*mcArray*/) const
294 //checking the family
297 Int_t pdgGranma = CheckOrigin();
299 if (pdgGranma == -99999){
300 AliDebug(2,"This particle does not have a quark in his genealogy\n");
303 if (pdgGranma == -9999){
304 AliDebug(2,"This particle come from a B decay channel but according to the settings of the task, we keep only the prompt charm particles\n");
308 if (pdgGranma == -999){
309 AliDebug(2,"This particle come from a prompt charm particles but according to the settings of the task, we want only the ones coming from B\n");
313 if (!CheckMCDaughters()) {
314 AliDebug(3, "CheckMCDaughters false");
317 if (!CheckMCChannelDecay()) {
318 AliDebug(3,"CheckMCChannelDecay false");
324 //_________________________________________________________________________________________________
325 Int_t AliCFVertexingHF::CheckOrigin() const
328 // checking whether the mother of the particles come from a charm or a bottom quark
333 mother = fmcPartCandidate->GetMother();
335 Int_t abspdgGranma =0;
336 Bool_t isFromB=kFALSE;
337 Bool_t isQuarkFound=kFALSE;
340 AliDebug(2,Form("mother at step %d = %d", istep, mother));
341 AliAODMCParticle* mcGranma = dynamic_cast<AliAODMCParticle*>(fmcArray->At(mother));
343 pdgGranma = mcGranma->GetPdgCode();
344 AliDebug(2,Form("Pdg mother at step %d = %d", istep, pdgGranma));
345 abspdgGranma = TMath::Abs(pdgGranma);
346 if ((abspdgGranma > 500 && abspdgGranma < 600) || (abspdgGranma > 5000 && abspdgGranma < 6000)){
349 if(abspdgGranma==4 || abspdgGranma==5) isQuarkFound=kTRUE;
350 mother = mcGranma->GetMother();
352 AliError("Failed casting the mother particle!");
357 if(fRejectIfNoQuark && !isQuarkFound) return -99999;
359 if (!fKeepDfromB) return -9999; //skip particle if come from a B meson.
362 if (fKeepDfromBOnly) return -999;
367 //___________________________________________
368 Bool_t AliCFVertexingHF::CheckMCDaughters()const
371 // checking the daughters
374 AliAODMCParticle *mcPartDaughter;
375 Bool_t checkDaughters = kFALSE;
377 Int_t label0 = fmcPartCandidate->GetDaughter(0);
378 Int_t label1 = fmcPartCandidate->GetDaughter(1);
379 AliDebug(3,Form("label0 = %d, label1 = %d",label0,label1));
380 if (label1==0 || label0 == 0){
381 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
382 return checkDaughters;
385 if (fLabelArray == 0x0) {
386 return checkDaughters;
389 for (Int_t iProng = 0; iProng<fProngs; iProng++){
390 mcPartDaughter = dynamic_cast<AliAODMCParticle*>(fmcArray->At(fLabelArray[iProng]));
391 if (!mcPartDaughter) {
392 AliWarning("At least one Daughter Particle not found in tree, skipping");
393 return checkDaughters;
397 checkDaughters = kTRUE;
398 return checkDaughters;
401 //______________________________________________________
402 Bool_t AliCFVertexingHF::FillMCContainer(Double_t *containerInputMC)
405 // fill the container for Generator level selection
408 Bool_t mcContainerFilled = kFALSE;
410 Double_t* vectorMC = new Double_t[fNVar];
411 for (Int_t iVar = 0; iVar<fNVar; iVar++) vectorMC[iVar]= 9999.;
413 if (GetGeneratedValuesFromMCParticle(&vectorMC[0])){
414 for (Int_t iVar = 0; iVar<fNVar; iVar++){
415 containerInputMC[iVar] = vectorMC[iVar];
417 mcContainerFilled = kTRUE;
421 return mcContainerFilled;
424 //______________________________________________________
425 Bool_t AliCFVertexingHF::FillRecoContainer(Double_t *containerInput)
428 // fill the container for Reconstrucred level selection
431 Bool_t recoContainerFilled = kFALSE;
432 Double_t* vectorValues = new Double_t[fNVar];
433 Double_t* vectorReco = new Double_t[fNVar];
434 for (Int_t iVar = 0; iVar<fNVar; iVar++) {
436 vectorValues[iVar]= 9999.;
437 vectorReco[iVar]=9999.;
440 if(fFillFromGenerated){
441 //filled with MC values
442 if (GetGeneratedValuesFromMCParticle(&vectorValues[0])){
443 for (Int_t iVar = 0; iVar<fNVar; iVar++){
444 containerInput[iVar] = vectorValues[iVar];
446 recoContainerFilled = kTRUE;
450 //filled with Reco values
452 if (GetRecoValuesFromCandidate(&vectorReco[0])){
453 for (Int_t iVar = 0; iVar<fNVar; iVar++){
454 containerInput[iVar] = vectorReco[iVar];
456 recoContainerFilled = kTRUE;
460 delete [] vectorValues;
461 delete [] vectorReco;
464 return recoContainerFilled;
467 //_____________________________________________________
468 Bool_t AliCFVertexingHF::MCAcceptanceStep() const
471 // checking the MC acceptance step
474 Bool_t bMCAccStep = kFALSE;
476 AliAODMCParticle *mcPartDaughter;
477 Int_t label0 = fmcPartCandidate->GetDaughter(0);
478 Int_t label1 = fmcPartCandidate->GetDaughter(1);
479 if (label1==0 || label0 == 0){
480 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
484 if (fLabelArray == 0x0) {
488 for (Int_t iProng = 0; iProng<fProngs; iProng++){
489 mcPartDaughter = dynamic_cast<AliAODMCParticle*>(fmcArray->At(fLabelArray[iProng]));
490 if (!mcPartDaughter) {
491 AliWarning("At least one Daughter Particle not found in tree, skipping");
494 Double_t eta = mcPartDaughter->Eta();
495 Double_t pt = mcPartDaughter->Pt();
497 //set values of eta and pt in the constructor.
498 // if (TMath::Abs(eta) > 0.9 || pt < 0.1){
499 if (TMath::Abs(eta) > fEtaAccCut[iProng] || pt < fPtAccCut[iProng]){
500 AliDebug(3,Form("At least one daughter has eta or pt outside the required range (|eta| = %f, pt = %f, should be |eta| < %f, pt > %f \n", TMath::Abs(eta), pt, fEtaAccCut[iProng], fPtAccCut[iProng]));
508 //_____________________________________________________
509 Bool_t AliCFVertexingHF::MCRefitStep(AliAODEvent *aodEvent, AliESDtrackCuts **trackCuts) const
512 // check on the kTPCrefit and kITSrefit conditions of the daughters
514 Bool_t bRefitStep = kFALSE;
516 Int_t label0 = fmcPartCandidate->GetDaughter(0);
517 Int_t label1 = fmcPartCandidate->GetDaughter(1);
519 if (label1==0 || label0 == 0){
520 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
524 if (fLabelArray == 0x0) {
528 Int_t foundDaughters = 0;
529 Int_t* temp = new Int_t[fProngs];
530 for (Int_t ilabel = 0; ilabel<fProngs; ilabel++){
531 temp[ilabel] = fLabelArray[ilabel];
534 // if (trackCuts->GetRequireTPCRefit() || trackCuts->GetRequireITSRefit()){
536 for(Int_t iaod =0; iaod<aodEvent->GetNumberOfTracks(); iaod++){
537 AliAODTrack *track = (AliAODTrack*)aodEvent->GetTrack(iaod);
538 if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
539 Bool_t foundTrack = kFALSE;
541 for (Int_t ilabel = 0; ilabel<fProngs; ilabel++){
542 AliDebug(3,Form("fLabelArray[%d] = %d, track->GetLabel() = %d",ilabel,fLabelArray[ilabel],TMath::Abs(track->GetLabel())));
543 if ((track->GetLabel()<0)&&(fFakeSelection==1)) continue;
544 if ((track->GetLabel()>0)&&(fFakeSelection==2)) continue;
546 if (TMath::Abs(track->GetLabel()) == temp[ilabel]) {
555 AliDebug(4,Form("daughter %d \n",foundDaughters));
556 if(trackCuts[prongindex]->GetRequireTPCRefit()){
557 if(track->GetStatus()&AliESDtrack::kTPCrefit) {
561 AliDebug(3, "Refit cut not passed , missing TPC refit\n");
568 if (trackCuts[prongindex]->GetRequireITSRefit()) {
569 if(track->GetStatus()&AliESDtrack::kITSrefit){
573 AliDebug(3, "Refit cut not passed , missing ITS refit\n");
580 if (foundDaughters == fProngs){
587 if (foundDaughters== fProngs) return bRefitStep;
591 //____________________________________________________________________________
593 Bool_t AliCFVertexingHF::RecoStep()
596 //check also vertex and ITS Refit and TPC Refit
599 Bool_t bRecoStep = kFALSE;
600 Int_t mcLabel = GetMCLabel();
603 AliDebug(2,"No MC particle found");
607 fmcPartCandidate = (AliAODMCParticle*)fmcArray->At(mcLabel);
608 if (!fmcPartCandidate){
609 AliWarning("Could not find associated MC in AOD MC tree");
614 Int_t pdgGranma = CheckOrigin();
616 if (pdgGranma == -99999){
617 AliDebug(2,"This particle does not have a quark in his genealogy\n");
620 if (pdgGranma == -9999){
621 AliDebug(2,"This particle come from a B decay channel but according to the settings of the task, we keep only prompt charm particles\n");
625 if (pdgGranma == -999){
626 AliDebug(2,"This particle come from a prompt charm particle but according to the settings of the task, we want only the ones coming from B\n");
633 //____________________________________________
634 Double_t AliCFVertexingHF::GetEtaProng(Int_t iProng) const
637 // getting eta of the prong
641 Double_t etaProng = fRecoCandidate->EtaProng(iProng);
646 //______________________________________________________
647 Double_t AliCFVertexingHF::GetPtProng(Int_t iProng) const
650 // getting pt of the prong
654 Double_t ptProng = fRecoCandidate->PtProng(iProng);
661 //____________________________________________________________________
663 Bool_t AliCFVertexingHF::RecoAcceptStep(AliESDtrackCuts **trackCuts) const
666 // reco Acceptance step
669 Bool_t bRecoAccStep = kFALSE;
671 Float_t etaCutMin, ptCutMin, etaCutMax, ptCutMax;
673 Float_t etaProng=0., ptProng=0.;
675 for (Int_t iProng =0; iProng<fProngs; iProng++){
677 trackCuts[iProng]->GetEtaRange(etaCutMin, etaCutMax);
678 trackCuts[iProng]->GetPtRange(ptCutMin, ptCutMax);
679 etaProng = GetEtaProng(iProng);
680 ptProng = GetPtProng(iProng);
682 Bool_t acceptanceProng = (etaProng>etaCutMin && etaProng<etaCutMax && ptProng>ptCutMin && ptProng<ptCutMax);
683 if (!acceptanceProng) {
684 AliDebug(2,"At least one reconstructed prong isn't in the acceptance\n");
692 //___________________________________________________________
694 Bool_t AliCFVertexingHF::FillUnfoldingMatrix(Double_t fill[4]) const
697 // filling the unfolding matrix
700 if(fmcPartCandidate){
702 fill[0] = GetPtCand();
703 fill[1] = GetYCand();
705 fill[2] = fmcPartCandidate->Pt();
706 fill[3] = fmcPartCandidate->Y();
713 //___________________________________________________________
715 Int_t AliCFVertexingHF::CheckReflexion(Char_t isSign)
718 // check for reflexion (particle/antiparticle)
721 Int_t mcLabel = GetMCLabel();
724 AliDebug(2,"No MC particle found");
728 fmcPartCandidate = (AliAODMCParticle*)fmcArray->At(mcLabel);
729 if (!fmcPartCandidate){
730 AliWarning("Could not find associated MC in AOD MC tree");
735 if(fmcPartCandidate->GetPdgCode()>0) {
736 if (isSign == 1){ // I ask for antiparticle only
737 AliDebug(2,"candidate is particle, I ask for antiparticle only");
740 return 1; // particle
742 else if(fmcPartCandidate->GetPdgCode()<0) {
743 if (isSign == 0){ // I ask for particle only
744 AliDebug(2,"candidate is antiparticle, I ask for particle only");
747 return 2; // antiparticle
749 else return 0; // ....shouldn't be...
752 //___________________________________________________________
754 Bool_t AliCFVertexingHF::SetLabelArray()
757 // setting the label arrays
760 Bool_t bLabelArray = kFALSE;
762 fLabelArray = new Int_t[fProngs];
764 AliAODMCParticle *mcPartDaughter;
765 Int_t label0 = fmcPartCandidate->GetDaughter(0);
766 Int_t label1 = fmcPartCandidate->GetDaughter(1);
767 AliDebug(2,Form("label0 = %d, label1 = %d",label0,label1));
768 if (label1==0 || label0 == 0){
769 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
770 delete [] fLabelArray;
775 if (label1 - label0 == fProngs-1){
776 for (Int_t iProng = 0; iProng<fProngs; iProng++){
777 mcPartDaughter = dynamic_cast<AliAODMCParticle*>(fmcArray->At(label0+iProng));
779 fLabelArray[iProng] = mcPartDaughter->GetLabel();
782 AliError("Failed casting the daughter particle, returning a NULL label array");
783 delete [] fLabelArray;
790 // resonant decay channel
791 else if (label1 - label0 == fProngs-2 && fProngs > 2){
792 Int_t labelFirstDau = fmcPartCandidate->GetDaughter(0);
793 Int_t foundDaughters = 0;
794 for(Int_t iDau=0; iDau<fProngs-1; iDau++){
795 Int_t iLabelDau = labelFirstDau+iDau;
796 AliAODMCParticle* part = dynamic_cast<AliAODMCParticle*>(fmcArray->At(iLabelDau));
798 AliError("Wrong particle type in fmcArray");
799 delete [] fLabelArray;
803 Int_t pdgCode=TMath::Abs(part->GetPdgCode());
804 if(pdgCode==211 || pdgCode==321 || pdgCode==2212){
806 fLabelArray[foundDaughters] = part->GetLabel();
810 AliError("Error while casting particle! returning a NULL array");
811 delete [] fLabelArray;
817 Int_t nDauRes=part->GetNDaughters();
819 delete [] fLabelArray;
823 Int_t labelFirstDauRes = part->GetDaughter(0);
824 for(Int_t iDauRes=0; iDauRes<nDauRes; iDauRes++){
825 Int_t iLabelDauRes = labelFirstDauRes+iDauRes;
826 AliAODMCParticle* dauRes = dynamic_cast<AliAODMCParticle*>(fmcArray->At(iLabelDauRes));
828 fLabelArray[foundDaughters] = dauRes->GetLabel();
832 AliError("Error while casting resonant daughter! returning a NULL array");
833 delete [] fLabelArray;
840 if (foundDaughters != fProngs){
841 delete [] fLabelArray;
846 // wrong correspondance label <--> prongs
848 delete [] fLabelArray;
852 SetAccCut(); // setting the pt and eta acceptance cuts
857 //___________________________________________________________
859 void AliCFVertexingHF::SetPtAccCut(Float_t* ptAccCut)
862 // setting the pt cut to be used in the Acceptance steps (MC+Reco)
866 for (Int_t iP=0; iP<fProngs; iP++){
867 fPtAccCut[iP]=ptAccCut[iP];
875 //___________________________________________________________
877 void AliCFVertexingHF::SetEtaAccCut(Float_t* etaAccCut)
880 // setting the eta cut to be used in the Acceptance steps (MC+Reco)
884 for (Int_t iP=0; iP<fProngs; iP++){
885 fEtaAccCut[iP]=etaAccCut[iP];
890 //___________________________________________________________
892 void AliCFVertexingHF::SetAccCut(Float_t* ptAccCut, Float_t* etaAccCut)
895 // setting the pt and eta cut to be used in the Acceptance steps (MC+Reco)
899 for (Int_t iP=0; iP<fProngs; iP++){
900 fPtAccCut[iP]=ptAccCut[iP];
901 fEtaAccCut[iP]=etaAccCut[iP];
907 //___________________________________________________________
909 void AliCFVertexingHF::SetAccCut()
912 // setting the pt and eta cut to be used in the Acceptance steps (MC+Reco)
916 for (Int_t iP=0; iP<fProngs; iP++){