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 **************************************************************************/
16 //-----------------------------------------------------------------------
17 // Class for HF corrections as a function of many variables and step
18 // Author : C. Zampolli, CERN
19 // D. Caffarri, Univ & INFN Padova caffarri@pd.infn.it
20 // Base class for HF Unfolding - agrelli@uu.nl
21 //-----------------------------------------------------------------------
23 #include "TParticle.h"
24 #include "TClonesArray.h"
25 #include "AliAODMCParticle.h"
26 #include "AliAODRecoDecayHF.h"
27 #include "AliAODRecoDecayHF2Prong.h"
28 #include "AliAODRecoDecayHF3Prong.h"
29 #include "AliAODRecoDecayHF4Prong.h"
30 #include "AliAODMCHeader.h"
31 #include "AliAODEvent.h"
33 #include "AliESDtrackCuts.h"
34 #include "AliESDtrack.h"
36 #include "AliCFVertexingHF.h"
38 //___________________________________________________________
39 AliCFVertexingHF::AliCFVertexingHF() :
42 fmcPartCandidate(0x0),
47 fFillFromGenerated(0),
50 fKeepDfromBOnly(kFALSE),
65 //_____________________________________________________
66 AliCFVertexingHF::AliCFVertexingHF(TClonesArray *mcArray, UShort_t originDselection) :
69 fmcPartCandidate(0x0),
74 fFillFromGenerated(0),
77 fKeepDfromBOnly(kFALSE),
83 // constructor with mcArray
86 SetDselection(originDselection);
90 //_______________________________________________________
91 AliCFVertexingHF::~AliCFVertexingHF()
97 if (fmcArray) fmcArray = 0x0;
98 if (fRecoCandidate) fRecoCandidate = 0x0;
99 if (fmcPartCandidate) fmcPartCandidate = 0x0;
101 delete [] fLabelArray;
106 //_____________________________________________________
107 AliCFVertexingHF& AliCFVertexingHF::operator=(const AliCFVertexingHF& c)
110 // assigment operator
114 TObject::operator=(c);
115 fmcArray = c.fmcArray;
116 fRecoCandidate = c.fRecoCandidate;
117 fmcPartCandidate = c.fmcPartCandidate;
118 fNDaughters = c.fNDaughters;
120 fzPrimVertex = c.fzPrimVertex;
121 fzMCVertex = c.fzMCVertex;
122 fFillFromGenerated = c.fFillFromGenerated;
123 fOriginDselection = c.fOriginDselection;
124 fKeepDfromB = c.fKeepDfromB;
125 fKeepDfromBOnly = c.fKeepDfromBOnly;
126 fmcLabel = c.fmcLabel;
129 fLabelArray = new Int_t[fProngs];
130 for(Int_t iP=0; iP<fProngs; iP++)fLabelArray[iP]=c.fLabelArray[iP];
137 //____________________________________________________
138 AliCFVertexingHF::AliCFVertexingHF(const AliCFVertexingHF &c) :
140 fmcArray(c.fmcArray),
141 fRecoCandidate(c.fRecoCandidate),
142 fmcPartCandidate(c.fmcPartCandidate),
143 fNDaughters(c.fNDaughters),
145 fzPrimVertex(c.fzPrimVertex),
146 fzMCVertex(c.fzMCVertex),
147 fFillFromGenerated(c.fFillFromGenerated),
148 fOriginDselection (c.fOriginDselection),
149 fKeepDfromB (c.fKeepDfromB),
150 fKeepDfromBOnly (c.fKeepDfromBOnly),
151 fmcLabel(c.fmcLabel),
159 fLabelArray = new Int_t[fProngs];
160 if (c.fLabelArray) memcpy(fLabelArray,c.fLabelArray,fProngs*sizeof(Int_t));
164 //___________________________________________________________
165 void AliCFVertexingHF::SetDselection(UShort_t originDselection)
167 // setting the way the D0 will be selected
168 // 0 --> only from c quarks
169 // 1 --> only from b quarks
170 // 2 --> from both c quarks and b quarks
172 fOriginDselection = originDselection;
174 if (fOriginDselection == 0) {
175 fKeepDfromB = kFALSE;
176 fKeepDfromBOnly = kFALSE;
179 if (fOriginDselection == 1) {
181 fKeepDfromBOnly = kTRUE;
184 if (fOriginDselection == 2) {
186 fKeepDfromBOnly = kFALSE;
192 //______________________________________________________
193 void AliCFVertexingHF::SetMCCandidateParam(Int_t label)
196 // setting the parameters (candidate and n. daughters)
199 fmcPartCandidate = dynamic_cast <AliAODMCParticle*> (fmcArray->At(label));
200 fNDaughters = fmcPartCandidate->GetNDaughters();
204 //____________________________________________________________
205 Int_t AliCFVertexingHF::MCcquarkCounting(AliAODMCParticle* mcPart) const
208 // counting the c-quarks
212 if (mcPart->GetPdgCode() == 4) cquarks++;
213 if (mcPart->GetPdgCode() == -4) cquarks++;
215 AliWarning("Particle not found in tree, skipping\n");
222 //________________________________________________________
223 Bool_t AliCFVertexingHF::CheckMCPartFamily(AliAODMCParticle */*mcPart*/, TClonesArray */*mcArray*/) const
226 //checking the family
229 Int_t pdgGranma = CheckOrigin();
230 if (pdgGranma == -9999){
231 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");
235 if (pdgGranma == -999){
236 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");
240 if (!CheckMCDaughters()) {
241 AliDebug(3, "CheckMCDaughters false");
244 if (!CheckMCChannelDecay()) {
245 AliDebug(3,"CheckMCChannelDecay false");
251 //_________________________________________________________________________________________________
252 Int_t AliCFVertexingHF::CheckOrigin() const
255 // checking whether the mother of the particles come from a charm or a bottom quark
260 mother = fmcPartCandidate->GetMother();
262 Int_t abspdgGranma =0;
265 AliDebug(2,Form("mother at step %d = %d", istep, mother));
266 AliAODMCParticle* mcGranma = dynamic_cast<AliAODMCParticle*>(fmcArray->At(mother));
267 pdgGranma = mcGranma->GetPdgCode();
268 AliDebug(2,Form("Pdg mother at step %d = %d", istep, pdgGranma));
269 abspdgGranma = TMath::Abs(pdgGranma);
270 if ((abspdgGranma > 500 && abspdgGranma < 600) || (abspdgGranma > 5000 && abspdgGranma < 6000)) {
271 if (!fKeepDfromB) return -9999; //skip particle if come from a B meson.
277 mother = mcGranma->GetMother();
279 if (!((abspdgGranma > 500 && abspdgGranma < 600) || (abspdgGranma > 5000 && abspdgGranma < 6000))){
280 if (fKeepDfromBOnly) return -999;
285 //___________________________________________
286 Bool_t AliCFVertexingHF::CheckMCDaughters()const
289 // checking the daughters
292 AliAODMCParticle *mcPartDaughter;
293 Bool_t checkDaughters = kFALSE;
295 Int_t label0 = fmcPartCandidate->GetDaughter(0);
296 Int_t label1 = fmcPartCandidate->GetDaughter(1);
297 AliDebug(3,Form("label0 = %d, label1 = %d",label0,label1));
298 if (label1==0 || label0 == 0){
299 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
300 return checkDaughters;
303 if (fLabelArray == 0x0) {
304 return checkDaughters;
307 for (Int_t iProng = 0; iProng<fProngs; iProng++){
308 mcPartDaughter = dynamic_cast<AliAODMCParticle*>(fmcArray->At(fLabelArray[iProng]));
309 if (!mcPartDaughter) {
310 AliWarning("At least one Daughter Particle not found in tree, skipping");
311 return checkDaughters;
315 checkDaughters = kTRUE;
316 return checkDaughters;
319 //______________________________________________________
320 Bool_t AliCFVertexingHF::FillMCContainer(Double_t *containerInputMC)
323 // fill the container for Generator level selection
326 Bool_t mcContainerFilled = kFALSE;
328 Double_t* vectorMC = new Double_t[fNVar];
329 for (Int_t iVar = 0; iVar<fNVar; iVar++) vectorMC[iVar]= 9999.;
331 if (GetGeneratedValuesFromMCParticle(&vectorMC[0])){
332 for (Int_t iVar = 0; iVar<fNVar; iVar++){
333 containerInputMC[iVar] = vectorMC[iVar];
335 mcContainerFilled = kTRUE;
339 return mcContainerFilled;
342 //______________________________________________________
343 Bool_t AliCFVertexingHF::FillRecoContainer(Double_t *containerInput)
346 // fill the container for Reconstrucred level selection
349 Bool_t recoContainerFilled = kFALSE;
350 Double_t* vectorValues = new Double_t[fNVar];
351 Double_t* vectorReco = new Double_t[fNVar];
353 for (Int_t iVar = 0; iVar<fNVar; iVar++) {
354 vectorValues[iVar]= 9999.;
355 vectorReco[iVar]=9999.;
358 if(fFillFromGenerated){
359 //filled with MC values
360 if (GetGeneratedValuesFromMCParticle(&vectorValues[0])){
361 for (Int_t iVar = 0; iVar<fNVar; iVar++){
362 containerInput[iVar] = vectorValues[iVar];
364 recoContainerFilled = kTRUE;
368 //filled with Reco values
370 if (GetRecoValuesFromCandidate(&vectorReco[0])){
371 for (Int_t iVar = 0; iVar<fNVar; iVar++){
372 containerInput[iVar] = vectorReco[iVar];
374 recoContainerFilled = kTRUE;
378 delete [] vectorValues;
379 delete [] vectorReco;
382 return recoContainerFilled;
385 //_____________________________________________________
386 Bool_t AliCFVertexingHF::MCAcceptanceStep() const
389 // checking the MC acceptance step
392 Bool_t bMCAccStep = kFALSE;
394 AliAODMCParticle *mcPartDaughter;
395 Int_t label0 = fmcPartCandidate->GetDaughter(0);
396 Int_t label1 = fmcPartCandidate->GetDaughter(1);
397 if (label1==0 || label0 == 0){
398 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
402 if (fLabelArray == 0x0) {
406 for (Int_t iProng = 0; iProng<fProngs; iProng++){
407 mcPartDaughter = dynamic_cast<AliAODMCParticle*>(fmcArray->At(fLabelArray[iProng]));
408 if (!mcPartDaughter) {
409 AliWarning("At least one Daughter Particle not found in tree, skipping");
412 Double_t eta = mcPartDaughter->Eta();
413 Double_t pt = mcPartDaughter->Pt();
415 //set values of eta and pt in the constructor.
416 if (TMath::Abs(eta) > 0.9 || pt < 0.1){
417 AliDebug(3,"At least one daughter has eta>0.9 or pt < 0.1 \n");
425 //_____________________________________________________
426 Bool_t AliCFVertexingHF::MCRefitStep(AliAODEvent *aodEvent, AliESDtrackCuts *trackCuts) const
429 // check on the kTPCrefit and kITSrefit conditions of the daughters
431 Bool_t bRefitStep = kFALSE;
433 Int_t label0 = fmcPartCandidate->GetDaughter(0);
434 Int_t label1 = fmcPartCandidate->GetDaughter(1);
436 if (label1==0 || label0 == 0){
437 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
441 if (fLabelArray == 0x0) {
445 Int_t foundDaughters = 0;
446 Int_t* temp = new Int_t[fProngs];
447 for (Int_t ilabel = 0; ilabel<fProngs; ilabel++){
448 temp[ilabel] = fLabelArray[ilabel];
451 if (trackCuts->GetRequireTPCRefit() || trackCuts->GetRequireITSRefit()){
453 for(Int_t iaod =0; iaod<aodEvent->GetNumberOfTracks(); iaod++){
454 AliAODTrack *track = (AliAODTrack*)aodEvent->GetTrack(iaod);
455 if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
456 Bool_t foundTrack = kFALSE;
457 for (Int_t ilabel = 0; ilabel<fProngs; ilabel++){
458 AliDebug(3,Form("fLabelArray[%d] = %d, track->GetLabel() = %d",ilabel,fLabelArray[ilabel],track->GetLabel()));
459 if (track->GetLabel() == temp[ilabel]) {
467 AliDebug(4,Form("daughter %d \n",foundDaughters));
468 if(trackCuts->GetRequireTPCRefit()){
469 if(track->GetStatus()&AliESDtrack::kTPCrefit) {
473 AliDebug(3, "Refit cut not passed , missing TPC refit\n");
480 if (trackCuts->GetRequireITSRefit()) {
481 if(track->GetStatus()&AliESDtrack::kITSrefit){
485 AliDebug(3, "Refit cut not passed , missing ITS refit\n");
492 if (foundDaughters == fProngs){
499 if (foundDaughters== fProngs) return bRefitStep;
503 //____________________________________________________________________________
505 Bool_t AliCFVertexingHF::RecoStep()
508 //check also vertex and ITS Refit and TPC Refit
511 Bool_t bRecoStep = kFALSE;
512 Int_t mcLabel = GetMCLabel();
515 AliDebug(2,"No MC particle found");
519 fmcPartCandidate = (AliAODMCParticle*)fmcArray->At(mcLabel);
520 if (!fmcPartCandidate){
521 AliWarning("Could not find associated MC in AOD MC tree");
526 Int_t pdgGranma = CheckOrigin();
528 if (pdgGranma == -9999){
529 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");
533 if (pdgGranma == -999){
534 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");
541 //____________________________________________
542 Double_t AliCFVertexingHF::GetEtaProng(Int_t iProng) const
545 // getting eta of the prong
549 Double_t etaProng = fRecoCandidate->EtaProng(iProng);
554 //______________________________________________________
555 Double_t AliCFVertexingHF::GetPtProng(Int_t iProng) const
558 // getting pt of the prong
562 Double_t ptProng = fRecoCandidate->PtProng(iProng);
569 //____________________________________________________________________
571 Bool_t AliCFVertexingHF::RecoAcceptStep(AliESDtrackCuts *trackCuts) const
574 // reco Acceptance step
577 Bool_t bRecoAccStep = kFALSE;
579 Float_t etaCutMin, ptCutMin, etaCutMax, ptCutMax;
580 trackCuts->GetEtaRange(etaCutMin, etaCutMax);
581 trackCuts->GetPtRange(ptCutMin, ptCutMax);
583 Float_t etaProng=0., ptProng=0.;
585 for (Int_t iProng =0; iProng<fProngs; iProng++){
587 etaProng = GetEtaProng(iProng);
588 ptProng = GetPtProng(iProng);
590 Bool_t acceptanceProng = (etaProng>etaCutMin && etaProng<etaCutMax && ptProng>ptCutMin && ptProng<ptCutMax);
591 if (!acceptanceProng) {
592 AliDebug(2,"At least one reconstructed prong isn't in the acceptance\n");
600 //___________________________________________________________
602 Bool_t AliCFVertexingHF::FillUnfoldingMatrix(Double_t *fill) const
605 // filling the unfolding matrix
608 fill = new Double_t[4];
610 if(fmcPartCandidate){
612 fill[0] = GetPtCand();
613 fill[1] = GetYCand();
615 fill[2] = fmcPartCandidate->Pt();
616 fill[3] = fmcPartCandidate->Y();
625 //___________________________________________________________
627 Int_t AliCFVertexingHF::CheckReflexion(Char_t isSign)
630 // check for reflexion (particle/antiparticle)
633 Int_t mcLabel = GetMCLabel();
636 AliDebug(2,"No MC particle found");
640 fmcPartCandidate = (AliAODMCParticle*)fmcArray->At(mcLabel);
641 if (!fmcPartCandidate){
642 AliWarning("Could not find associated MC in AOD MC tree");
647 if(fmcPartCandidate->GetPdgCode()>0) {
648 if (isSign == 1){ // I ask for antiparticle only
649 AliDebug(2,"candidate is particle, I ask for antiparticle only");
652 return 1; // particle
654 else if(fmcPartCandidate->GetPdgCode()<0) {
655 if (isSign == 0){ // I ask for particle only
656 AliDebug(2,"candidate is antiparticle, I ask for particle only");
659 return 2; // antiparticle
661 else return 0; // ....shouldn't be...
664 //___________________________________________________________
666 Bool_t AliCFVertexingHF::SetLabelArray()
669 // setting the label arrays
672 Bool_t bLabelArray = kFALSE;
674 fLabelArray = new Int_t[fProngs];
676 AliAODMCParticle *mcPartDaughter;
677 Int_t label0 = fmcPartCandidate->GetDaughter(0);
678 Int_t label1 = fmcPartCandidate->GetDaughter(1);
679 AliDebug(2,Form("label0 = %d, label1 = %d",label0,label1));
680 if (label1==0 || label0 == 0){
681 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
682 delete [] fLabelArray;
687 if (label1 - label0 == fProngs-1){
688 for (Int_t iProng = 0; iProng<fProngs; iProng++){
689 mcPartDaughter = dynamic_cast<AliAODMCParticle*>(fmcArray->At(label0+iProng));
690 fLabelArray[iProng] = mcPartDaughter->GetLabel();
694 // resonant decay channel
695 else if (label1 - label0 == fProngs-2 && fProngs > 2){
696 Int_t labelFirstDau = fmcPartCandidate->GetDaughter(0);
697 Int_t foundDaughters = 0;
698 for(Int_t iDau=0; iDau<fProngs-1; iDau++){
699 Int_t iLabelDau = labelFirstDau+iDau;
700 AliAODMCParticle* part = dynamic_cast<AliAODMCParticle*>(fmcArray->At(iLabelDau));
701 Int_t pdgCode=TMath::Abs(part->GetPdgCode());
702 if(pdgCode==211 || pdgCode==321 || pdgCode==2212){
703 fLabelArray[foundDaughters] = part->GetLabel();
707 Int_t nDauRes=part->GetNDaughters();
709 delete [] fLabelArray;
713 Int_t labelFirstDauRes = part->GetDaughter(0);
714 for(Int_t iDauRes=0; iDauRes<nDauRes; iDauRes++){
715 Int_t iLabelDauRes = labelFirstDauRes+iDauRes;
716 AliAODMCParticle* dauRes = dynamic_cast<AliAODMCParticle*>(fmcArray->At(iLabelDauRes));
717 fLabelArray[foundDaughters] = dauRes->GetLabel();
722 if (foundDaughters != fProngs){
723 delete [] fLabelArray;
728 // wrong correspondance label <--> prongs
730 delete [] fLabelArray;