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();
264 AliDebug(2,Form("mother at step %d = %d", istep, mother));
265 AliAODMCParticle* mcGranma = dynamic_cast<AliAODMCParticle*>(fmcArray->At(mother));
266 pdgGranma = mcGranma->GetPdgCode();
267 AliDebug(2,Form("Pdg mother at step %d = %d", istep, pdgGranma));
268 Int_t abspdgGranma = TMath::Abs(pdgGranma);
269 if ((abspdgGranma > 500 && abspdgGranma < 600) || (abspdgGranma > 5000 && abspdgGranma < 6000)) {
270 if (!fKeepDfromB) return -9999; //skip particle if come from a B meson.
277 if (fKeepDfromBOnly) return -999;
280 mother = mcGranma->GetMother();
287 //___________________________________________
288 Bool_t AliCFVertexingHF::CheckMCDaughters()const
291 // checking the daughters
294 AliAODMCParticle *mcPartDaughter;
295 Bool_t checkDaughters = kFALSE;
297 Int_t label0 = fmcPartCandidate->GetDaughter(0);
298 Int_t label1 = fmcPartCandidate->GetDaughter(1);
299 AliDebug(3,Form("label0 = %d, label1 = %d",label0,label1));
300 if (label1==0 || label0 == 0){
301 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
302 return checkDaughters;
305 if (fLabelArray == 0x0) {
306 return checkDaughters;
309 for (Int_t iProng = 0; iProng<fProngs; iProng++){
310 mcPartDaughter = dynamic_cast<AliAODMCParticle*>(fmcArray->At(fLabelArray[iProng]));
311 if (!mcPartDaughter) {
312 AliWarning("At least one Daughter Particle not found in tree, skipping");
313 return checkDaughters;
317 checkDaughters = kTRUE;
318 return checkDaughters;
321 //______________________________________________________
322 Bool_t AliCFVertexingHF::FillMCContainer(Double_t *containerInputMC)
325 // fill the container for Generator level selection
328 Bool_t mcContainerFilled = kFALSE;
330 Double_t* vectorMC = new Double_t[fNVar];
331 for (Int_t iVar = 0; iVar<fNVar; iVar++) vectorMC[iVar]= 9999.;
333 if (GetGeneratedValuesFromMCParticle(&vectorMC[0])){
334 for (Int_t iVar = 0; iVar<fNVar; iVar++){
335 containerInputMC[iVar] = vectorMC[iVar];
337 mcContainerFilled = kTRUE;
341 return mcContainerFilled;
344 //______________________________________________________
345 Bool_t AliCFVertexingHF::FillRecoContainer(Double_t *containerInput)
348 // fill the container for Reconstrucred level selection
351 Bool_t recoContainerFilled = kFALSE;
352 Double_t* vectorValues = new Double_t[fNVar];
353 Double_t* vectorReco = new Double_t[fNVar];
355 for (Int_t iVar = 0; iVar<fNVar; iVar++) {
356 vectorValues[iVar]= 9999.;
357 vectorReco[iVar]=9999.;
360 if(fFillFromGenerated){
361 //filled with MC values
362 if (GetGeneratedValuesFromMCParticle(&vectorValues[0])){
363 for (Int_t iVar = 0; iVar<fNVar; iVar++){
364 containerInput[iVar] = vectorValues[iVar];
366 recoContainerFilled = kTRUE;
370 //filled with Reco values
372 if (GetRecoValuesFromCandidate(&vectorReco[0])){
373 for (Int_t iVar = 0; iVar<fNVar; iVar++){
374 containerInput[iVar] = vectorReco[iVar];
376 recoContainerFilled = kTRUE;
380 delete [] vectorValues;
381 delete [] vectorReco;
384 return recoContainerFilled;
387 //_____________________________________________________
388 Bool_t AliCFVertexingHF::MCAcceptanceStep() const
391 // checking the MC acceptance step
394 Bool_t bMCAccStep = kFALSE;
396 AliAODMCParticle *mcPartDaughter;
397 Int_t label0 = fmcPartCandidate->GetDaughter(0);
398 Int_t label1 = fmcPartCandidate->GetDaughter(1);
399 if (label1==0 || label0 == 0){
400 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
404 if (fLabelArray == 0x0) {
408 for (Int_t iProng = 0; iProng<fProngs; iProng++){
409 mcPartDaughter = dynamic_cast<AliAODMCParticle*>(fmcArray->At(fLabelArray[iProng]));
410 if (!mcPartDaughter) {
411 AliWarning("At least one Daughter Particle not found in tree, skipping");
414 Double_t eta = mcPartDaughter->Eta();
415 Double_t pt = mcPartDaughter->Pt();
417 //set values of eta and pt in the constructor.
418 if (TMath::Abs(eta) > 0.9 || pt < 0.1){
419 AliDebug(3,"At least one daughter has eta>0.9 or pt < 0.1 \n");
427 //_____________________________________________________
428 Bool_t AliCFVertexingHF::MCRefitStep(AliAODEvent *aodEvent, AliESDtrackCuts *trackCuts) const
431 // check on the kTPCrefit and kITSrefit conditions of the daughters
433 Bool_t bRefitStep = kFALSE;
435 Int_t label0 = fmcPartCandidate->GetDaughter(0);
436 Int_t label1 = fmcPartCandidate->GetDaughter(1);
438 if (label1==0 || label0 == 0){
439 AliDebug(2, Form("The MC particle doesn't have correct daughters, skipping!!"));
443 if (fLabelArray == 0x0) {
447 Int_t foundDaughters = 0;
448 Int_t* temp = new Int_t[fProngs];
449 for (Int_t ilabel = 0; ilabel<fProngs; ilabel++){
450 temp[ilabel] = fLabelArray[ilabel];
453 if (trackCuts->GetRequireTPCRefit() || trackCuts->GetRequireITSRefit()){
455 for(Int_t iaod =0; iaod<aodEvent->GetNumberOfTracks(); iaod++){
456 AliAODTrack *track = (AliAODTrack*)aodEvent->GetTrack(iaod);
457 if(track->GetStatus()&AliESDtrack::kITSpureSA) continue;
458 Bool_t foundTrack = kFALSE;
459 for (Int_t ilabel = 0; ilabel<fProngs; ilabel++){
460 AliDebug(3,Form("fLabelArray[%d] = %d, track->GetLabel() = %d",ilabel,fLabelArray[ilabel],track->GetLabel()));
461 if (track->GetLabel() == temp[ilabel]) {
469 AliDebug(4,Form("daughter %d \n",foundDaughters));
470 if(trackCuts->GetRequireTPCRefit()){
471 if(track->GetStatus()&AliESDtrack::kTPCrefit) {
475 AliDebug(3, "Refit cut not passed , missing TPC refit\n");
482 if (trackCuts->GetRequireITSRefit()) {
483 if(track->GetStatus()&AliESDtrack::kITSrefit){
487 AliDebug(3, "Refit cut not passed , missing ITS refit\n");
494 if (foundDaughters == fProngs){
501 if (foundDaughters== fProngs) return bRefitStep;
505 //____________________________________________________________________________
507 Bool_t AliCFVertexingHF::RecoStep()
510 //check also vertex and ITS Refit and TPC Refit
513 Bool_t bRecoStep = kFALSE;
514 Int_t mcLabel = GetMCLabel();
517 AliDebug(2,"No MC particle found");
521 fmcPartCandidate = (AliAODMCParticle*)fmcArray->At(mcLabel);
522 if (!fmcPartCandidate){
523 AliWarning("Could not find associated MC in AOD MC tree");
528 Int_t pdgGranma = CheckOrigin();
530 if (pdgGranma == -9999){
531 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");
535 if (pdgGranma == -999){
536 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");
543 //____________________________________________
544 Double_t AliCFVertexingHF::GetEtaProng(Int_t iProng) const
547 // getting eta of the prong
551 Double_t etaProng = fRecoCandidate->EtaProng(iProng);
556 //______________________________________________________
557 Double_t AliCFVertexingHF::GetPtProng(Int_t iProng) const
560 // getting pt of the prong
564 Double_t ptProng = fRecoCandidate->PtProng(iProng);
571 //____________________________________________________________________
573 Bool_t AliCFVertexingHF::RecoAcceptStep(AliESDtrackCuts *trackCuts) const
576 // reco Acceptance step
579 Bool_t bRecoAccStep = kFALSE;
581 Float_t etaCutMin, ptCutMin, etaCutMax, ptCutMax;
582 trackCuts->GetEtaRange(etaCutMin, etaCutMax);
583 trackCuts->GetPtRange(ptCutMin, ptCutMax);
585 Float_t etaProng=0., ptProng=0.;
587 for (Int_t iProng =0; iProng<fProngs; iProng++){
589 etaProng = GetEtaProng(iProng);
590 ptProng = GetPtProng(iProng);
592 Bool_t acceptanceProng = (etaProng>etaCutMin && etaProng<etaCutMax && ptProng>ptCutMin && ptProng<ptCutMax);
593 if (!acceptanceProng) {
594 AliDebug(2,"At least one reconstructed prong isn't in the acceptance\n");
602 //___________________________________________________________
604 Bool_t AliCFVertexingHF::FillUnfoldingMatrix(Double_t *fill) const
607 // filling the unfolding matrix
610 fill = new Double_t[4];
612 if(fmcPartCandidate){
614 fill[0] = GetPtCand();
615 fill[1] = GetYCand();
617 fill[2] = fmcPartCandidate->Pt();
618 fill[3] = fmcPartCandidate->Y();
627 //___________________________________________________________
629 Int_t AliCFVertexingHF::CheckReflexion()
632 // check for reflexion (particle/antiparticle)
635 Int_t mcLabel = GetMCLabel();
638 AliDebug(2,"No MC particle found");
642 fmcPartCandidate = (AliAODMCParticle*)fmcArray->At(mcLabel);
643 if (!fmcPartCandidate){
644 AliWarning("Could not find associated MC in AOD MC tree");
649 if(fmcPartCandidate->GetPdgCode()>0) return 1; // particle
650 else if(fmcPartCandidate->GetPdgCode()<0) return 2; // antiparticle
651 else return 0; // ....shouldn't be...
653 //___________________________________________________________
655 Bool_t AliCFVertexingHF::SetLabelArray()
658 // setting the label arrays
661 Bool_t bLabelArray = kFALSE;
663 fLabelArray = new Int_t[fProngs];
665 AliAODMCParticle *mcPartDaughter;
666 Int_t label0 = fmcPartCandidate->GetDaughter(0);
667 Int_t label1 = fmcPartCandidate->GetDaughter(1);
668 AliDebug(2,Form("label0 = %d, label1 = %d",label0,label1));
669 if (label1==0 || label0 == 0){
670 AliDebug(2, Form("The MC particle doesn't jave correct daughters, skipping!!"));
671 delete [] fLabelArray;
676 if (label1 - label0 == fProngs-1){
677 for (Int_t iProng = 0; iProng<fProngs; iProng++){
678 mcPartDaughter = dynamic_cast<AliAODMCParticle*>(fmcArray->At(label0+iProng));
679 fLabelArray[iProng] = mcPartDaughter->GetLabel();
683 // resonant decay channel
684 else if (label1 - label0 == fProngs-2 && fProngs > 2){
685 Int_t labelFirstDau = fmcPartCandidate->GetDaughter(0);
686 Int_t foundDaughters = 0;
687 for(Int_t iDau=0; iDau<fProngs-1; iDau++){
688 Int_t iLabelDau = labelFirstDau+iDau;
689 AliAODMCParticle* part = dynamic_cast<AliAODMCParticle*>(fmcArray->At(iLabelDau));
690 Int_t pdgCode=TMath::Abs(part->GetPdgCode());
691 if(pdgCode==211 || pdgCode==321 || pdgCode==2212){
692 fLabelArray[foundDaughters] = part->GetLabel();
696 Int_t nDauRes=part->GetNDaughters();
698 delete [] fLabelArray;
702 Int_t labelFirstDauRes = part->GetDaughter(0);
703 for(Int_t iDauRes=0; iDauRes<fProngs-1; iDauRes++){
704 Int_t iLabelDauRes = labelFirstDauRes+iDauRes;
705 AliAODMCParticle* dauRes = dynamic_cast<AliAODMCParticle*>(fmcArray->At(iLabelDauRes));
706 fLabelArray[foundDaughters] = dauRes->GetLabel();
711 if (foundDaughters != fProngs){
712 delete [] fLabelArray;
717 // wrong correspondance label <--> prongs
719 delete [] fLabelArray;