1 /**************************************************************************
2 * Copyright(c) 1998-2018, 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 AliAnalysisTaskCombinHF
20 // AliAnalysisTaskSE to build D meson candidates by combining tracks
21 // background is computed LS and track rotations is
22 // Authors: F. Prino, A. Rossi
23 /////////////////////////////////////////////////////////////
29 #include <THnSparse.h>
31 #include "AliAnalysisManager.h"
32 #include "AliInputEventHandler.h"
33 #include "AliPIDResponse.h"
34 #include "AliAODHandler.h"
35 #include "AliAODEvent.h"
36 #include "AliAODMCParticle.h"
37 #include "AliAODMCHeader.h"
38 #include "AliAODVertex.h"
39 #include "AliAODTrack.h"
40 #include "AliVertexingHFUtils.h"
41 #include "AliAnalysisTaskCombinHF.h"
43 ClassImp(AliAnalysisTaskCombinHF)
46 //________________________________________________________________________
47 AliAnalysisTaskCombinHF::AliAnalysisTaskCombinHF():
51 fHistTrackStatus(0x0),
52 fHistCheckOrigin(0x0),
53 fHistCheckOriginSel(0x0),
54 fHistCheckDecChan(0x0),
55 fHistCheckDecChanAcc(0x0),
57 fPtVsYGenLargeAcc(0x0),
63 fMassVsPtVsYLSpp(0x0),
64 fMassVsPtVsYLSmm(0x0),
66 fMassVsPtVsYRefl(0x0),
71 fDeltaMassFullAnalysis(0x0),
77 fPidHF(new AliAODPidHF()),
86 fMinAngleForRot(5*TMath::Pi()/6),
87 fMaxAngleForRot(7*TMath::Pi()/6),
88 fMinAngleForRot3(2*TMath::Pi()/6),
89 fMaxAngleForRot3(4*TMath::Pi()/6),
93 fPromptFeeddown(kPrompt),
96 fPIDstrategy(knSigma),
101 fBayesThresKaon(0.4),
102 fBayesThresPion(0.4),
103 fDoEventMixing(kTRUE),
104 fMaxNumberOfEventsForMixing(20),
105 fMaxzVertDistForMix(20.),
106 fMaxMultDiffForMix(9999.),
110 fNzVertPoolsLimSize(2),
113 fNMultPoolsLimSize(2),
121 // default constructor
124 //________________________________________________________________________
125 AliAnalysisTaskCombinHF::AliAnalysisTaskCombinHF(Int_t meson, AliRDHFCuts* analysiscuts):
126 AliAnalysisTaskSE("DmesonCombin"),
129 fHistTrackStatus(0x0),
130 fHistCheckOrigin(0x0),
131 fHistCheckOriginSel(0x0),
132 fHistCheckDecChan(0x0),
133 fHistCheckDecChanAcc(0x0),
135 fPtVsYGenLargeAcc(0x0),
136 fPtVsYGenLimAcc(0x0),
140 fMassVsPtVsYRot(0x0),
141 fMassVsPtVsYLSpp(0x0),
142 fMassVsPtVsYLSmm(0x0),
143 fMassVsPtVsYSig(0x0),
144 fMassVsPtVsYRefl(0x0),
145 fMassVsPtVsYBkg(0x0),
149 fDeltaMassFullAnalysis(0x0),
155 fPidHF(new AliAODPidHF()),
156 fAnalysisCuts(analysiscuts),
164 fMinAngleForRot(5*TMath::Pi()/6),
165 fMaxAngleForRot(7*TMath::Pi()/6),
166 fMinAngleForRot3(2*TMath::Pi()/6),
167 fMaxAngleForRot3(4*TMath::Pi()/6),
174 fPIDstrategy(knSigma),
179 fBayesThresKaon(0.4),
180 fBayesThresPion(0.4),
181 fDoEventMixing(kTRUE),
182 fMaxNumberOfEventsForMixing(20),
183 fMaxzVertDistForMix(20.),
184 fMaxMultDiffForMix(9999.),
188 fNzVertPoolsLimSize(2),
191 fNMultPoolsLimSize(2),
199 // standard constructor
201 DefineOutput(1,TList::Class()); //My private output
202 DefineOutput(2,AliNormalizationCounter::Class());
205 //________________________________________________________________________
206 AliAnalysisTaskCombinHF::~AliAnalysisTaskCombinHF()
211 if(fOutput && !fOutput->IsOwner()){
213 delete fHistTrackStatus;
214 delete fHistCheckOrigin;
215 delete fHistCheckOriginSel;
216 delete fHistCheckDecChan;
217 delete fHistCheckDecChanAcc;
219 delete fPtVsYGenLargeAcc;
220 delete fPtVsYGenLimAcc;
224 delete fMassVsPtVsYLSpp;
225 delete fMassVsPtVsYLSmm;
226 delete fMassVsPtVsYRot;
227 delete fMassVsPtVsYSig;
228 delete fMassVsPtVsYRefl;
229 delete fMassVsPtVsYBkg;
233 delete fDeltaMassFullAnalysis;
234 delete fMassVsPtVsYME;
239 delete fTrackCutsAll;
240 delete fTrackCutsPion;
241 delete fTrackCutsKaon;
243 delete fAnalysisCuts;
244 if(fKaonTracks) fKaonTracks->Delete();
245 if(fPionTracks) fPionTracks->Delete();
249 delete [] fzVertPoolLims;
250 delete [] fMultPoolLims;
253 //________________________________________________________________________
254 void AliAnalysisTaskCombinHF::ConfigureZVertPools(Int_t nPools, Double_t* zVertLimits)
256 // sets the pools for event mizing in zvertex
257 if(fzVertPoolLims) delete [] fzVertPoolLims;
259 fNzVertPoolsLimSize=nPools+1;
260 fzVertPoolLims = new Double_t[fNzVertPoolsLimSize];
261 for(Int_t ib=0; ib<fNzVertPoolsLimSize; ib++) fzVertPoolLims[ib]=zVertLimits[ib];
265 //________________________________________________________________________
266 void AliAnalysisTaskCombinHF::ConfigureMultiplicityPools(Int_t nPools, Double_t* multLimits)
268 // sets the pools for event mizing in zvertex
269 if(fMultPoolLims) delete [] fMultPoolLims;
271 fNMultPoolsLimSize=nPools+1;
272 fMultPoolLims = new Double_t[fNMultPoolsLimSize];
273 for(Int_t ib=0; ib<nPools+1; ib++) fMultPoolLims[ib]=multLimits[ib];
277 //________________________________________________________________________
278 void AliAnalysisTaskCombinHF::UserCreateOutputObjects()
280 // Create the output container
282 if(fDebug > 1) printf("AnalysisTaskCombinHF::UserCreateOutputObjects() \n");
284 fOutput = new TList();
286 fOutput->SetName("OutputHistos");
288 fHistNEvents = new TH1F("hNEvents", "number of events ",8,-0.5,7.5);
289 fHistNEvents->GetXaxis()->SetBinLabel(1,"nEventsAnal");
290 fHistNEvents->GetXaxis()->SetBinLabel(2,"n. passing IsEvSelected");
291 fHistNEvents->GetXaxis()->SetBinLabel(3,"n. rejected due to trigger");
292 fHistNEvents->GetXaxis()->SetBinLabel(4,"n. rejected due to not reco vertex");
293 fHistNEvents->GetXaxis()->SetBinLabel(5,"n. rejected for contr vertex");
294 fHistNEvents->GetXaxis()->SetBinLabel(6,"n. rejected for vertex out of accept");
295 fHistNEvents->GetXaxis()->SetBinLabel(7,"n. rejected for pileup events");
296 fHistNEvents->GetXaxis()->SetBinLabel(8,"no. of out centrality events");
298 fHistNEvents->GetXaxis()->SetNdivisions(1,kFALSE);
299 fHistNEvents->Sumw2();
300 fHistNEvents->SetMinimum(0);
301 fOutput->Add(fHistNEvents);
303 fHistTrackStatus = new TH1F("hTrackStatus", "",8,-0.5,7.5);
304 fHistTrackStatus->GetXaxis()->SetBinLabel(1,"Not OK");
305 fHistTrackStatus->GetXaxis()->SetBinLabel(2,"Track OK");
306 fHistTrackStatus->GetXaxis()->SetBinLabel(3,"Kaon, Not OK");
307 fHistTrackStatus->GetXaxis()->SetBinLabel(4,"Kaon OK");
308 fHistTrackStatus->GetXaxis()->SetBinLabel(5,"Pion, Not OK");
309 fHistTrackStatus->GetXaxis()->SetBinLabel(6,"Pion OK");
310 fHistTrackStatus->GetXaxis()->SetBinLabel(7,"Kaon||Pion, Not OK");
311 fHistTrackStatus->GetXaxis()->SetBinLabel(8,"Kaon||Pion OK");
312 fHistTrackStatus->GetXaxis()->SetNdivisions(1,kFALSE);
313 fHistTrackStatus->Sumw2();
314 fHistTrackStatus->SetMinimum(0);
315 fOutput->Add(fHistTrackStatus);
317 Int_t nPtBins = (Int_t)(fMaxPt/fPtBinWidth+0.001);
318 Double_t maxPt=fPtBinWidth*nPtBins;
322 fHistCheckOrigin=new TH1F("hCheckOrigin","",7,-1.5,5.5);
323 fHistCheckOrigin->Sumw2();
324 fHistCheckOrigin->SetMinimum(0);
325 fOutput->Add(fHistCheckOrigin);
327 fHistCheckOriginSel=new TH1F("hCheckOriginSel","",7,-1.5,5.5);
328 fHistCheckOriginSel->Sumw2();
329 fHistCheckOriginSel->SetMinimum(0);
330 fOutput->Add(fHistCheckOriginSel);
332 fHistCheckDecChan=new TH1F("hCheckDecChan","",7,-2.5,4.5);
333 fHistCheckDecChan->Sumw2();
334 fHistCheckDecChan->SetMinimum(0);
335 fOutput->Add(fHistCheckDecChan);
337 fHistCheckDecChanAcc=new TH1F("hCheckDecChanAcc","",7,-2.5,4.5);
338 fHistCheckDecChanAcc->Sumw2();
339 fHistCheckDecChanAcc->SetMinimum(0);
340 fOutput->Add(fHistCheckDecChanAcc);
342 fPtVsYGen= new TH2F("hPtVsYGen","",nPtBins,0.,maxPt,20,-1.,1.);
344 fPtVsYGen->SetMinimum(0);
345 fOutput->Add(fPtVsYGen);
347 fPtVsYGenLargeAcc= new TH2F("hPtVsYGenLargeAcc","",nPtBins,0.,maxPt,20,-1.,1.);
348 fPtVsYGenLargeAcc->Sumw2();
349 fPtVsYGenLargeAcc->SetMinimum(0);
350 fOutput->Add(fPtVsYGenLargeAcc);
352 fPtVsYGenLimAcc= new TH2F("hPtVsYGenLimAcc","",nPtBins,0.,maxPt,20,-1.,1.);
353 fPtVsYGenLimAcc->Sumw2();
354 fPtVsYGenLimAcc->SetMinimum(0);
355 fOutput->Add(fPtVsYGenLimAcc);
357 fPtVsYGenAcc= new TH2F("hPtVsYGenAcc","",nPtBins,0.,maxPt,20,-1.,1.);
358 fPtVsYGenAcc->Sumw2();
359 fPtVsYGenAcc->SetMinimum(0);
360 fOutput->Add(fPtVsYGenAcc);
362 fPtVsYReco= new TH2F("hPtVsYReco","",nPtBins,0.,maxPt,20,-1.,1.);
364 fPtVsYReco->SetMinimum(0);
365 fOutput->Add(fPtVsYReco);
369 Int_t nMassBins=fMaxMass*1000.-fMinMass*1000.;
370 Double_t maxm=fMinMass+nMassBins*0.001;
371 fMassVsPtVsY=new TH3F("hMassVsPtVsY","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
372 fMassVsPtVsY->Sumw2();
373 fMassVsPtVsY->SetMinimum(0);
374 fOutput->Add(fMassVsPtVsY);
376 fMassVsPtVsYRot=new TH3F("hMassVsPtVsYRot","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
377 fMassVsPtVsYRot->Sumw2();
378 fMassVsPtVsYRot->SetMinimum(0);
379 fOutput->Add(fMassVsPtVsYRot);
382 fMassVsPtVsYLSpp=new TH3F("hMassVsPtVsYLSpp","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
383 fMassVsPtVsYLSpp->Sumw2();
384 fMassVsPtVsYLSpp->SetMinimum(0);
385 fOutput->Add(fMassVsPtVsYLSpp);
386 fMassVsPtVsYLSmm=new TH3F("hMassVsPtVsYLSmm","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
387 fMassVsPtVsYLSmm->Sumw2();
388 fMassVsPtVsYLSmm->SetMinimum(0);
389 fOutput->Add(fMassVsPtVsYLSmm);
392 fMassVsPtVsYSig=new TH3F("hMassVsPtVsYSig","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
393 fMassVsPtVsYSig->Sumw2();
394 fMassVsPtVsYSig->SetMinimum(0);
395 fOutput->Add(fMassVsPtVsYSig);
397 fMassVsPtVsYRefl=new TH3F("hMassVsPtVsYRefl","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
398 fMassVsPtVsYRefl->Sumw2();
399 fMassVsPtVsYRefl->SetMinimum(0);
400 fOutput->Add(fMassVsPtVsYRefl);
402 fMassVsPtVsYBkg=new TH3F("hMassVsPtVsYBkg","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
403 fMassVsPtVsYBkg->Sumw2();
404 fMassVsPtVsYBkg->SetMinimum(0);
405 fOutput->Add(fMassVsPtVsYBkg);
407 fNSelected=new TH1F("hNSelected","",100,-0.5,99.5);
409 fNSelected->SetMinimum(0);
410 fOutput->Add(fNSelected);
412 fNormRotated=new TH1F("hNormRotated","",11,-0.5,10.5);
413 fNormRotated->Sumw2();
414 fNormRotated->SetMinimum(0);
415 fOutput->Add(fNormRotated);
417 fDeltaMass=new TH1F("hDeltaMass","",100,-0.4,0.4);
419 fDeltaMass->SetMinimum(0);
420 fOutput->Add(fDeltaMass);
422 Int_t binSparseDMassRot[5]={nMassBins,100,24,40,20};
423 Double_t edgeLowSparseDMassRot[5]={fMinMass,-0.4,0.,-4.,0};
424 Double_t edgeHighSparseDMassRot[5]={maxm,0.4,12.,4.,3.14};
425 fDeltaMassFullAnalysis=new THnSparseF("fDeltaMassFullAnalysis","fDeltaMassFullAnalysis;inv mass (GeV/c);#Delta inv mass (GeV/c) ; p_{T}^{D} (GeV/c); #Delta p_{T} (GeV/c); daughter angle (2prongs) (rad);",5,binSparseDMassRot,edgeLowSparseDMassRot,edgeHighSparseDMassRot);
426 fOutput->Add(fDeltaMassFullAnalysis);
428 fMassVsPtVsYME=new TH3F("hMassVsPtVsYME","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
429 fMassVsPtVsYME->Sumw2();
430 fMassVsPtVsYME->SetMinimum(0);
431 fOutput->Add(fMassVsPtVsYME);
434 //Counter for Normalization
435 fCounter = new AliNormalizationCounter("NormalizationCounter");
438 fKaonTracks = new TObjArray();
439 fPionTracks=new TObjArray();
440 fKaonTracks->SetOwner();
441 fPionTracks->SetOwner();
442 fEventBuffer = new TTree("EventBuffer", "Temporary buffer for event mixing");
443 fEventBuffer->Branch("zVertex", &fVtxZ);
444 fEventBuffer->Branch("multiplicity", &fMultiplicity);
445 fEventBuffer->Branch("karray", "TObjArray", &fKaonTracks);
446 fEventBuffer->Branch("parray", "TObjArray", &fPionTracks);
449 PostData(2,fCounter);
452 //________________________________________________________________________
453 void AliAnalysisTaskCombinHF::UserExec(Option_t */*option*/){
454 //Build the 3-track combinatorics (+-+ and -+-) for D+->Kpipi decays
456 AliAODEvent *aod = dynamic_cast<AliAODEvent*> (InputEvent());
457 if(!aod && AODEvent() && IsStandardAOD()) {
458 // In case there is an AOD handler writing a standard AOD, use the AOD
459 // event in memory rather than the input (ESD) event.
460 aod = dynamic_cast<AliAODEvent*> (AODEvent());
463 printf("AliAnalysisTaskCombinHF::UserExec: AOD not found!\n");
467 // fix for temporary bug in ESDfilter
468 // the AODs with null vertex pointer didn't pass the PhysSel
469 if(!aod->GetPrimaryVertex() || TMath::Abs(aod->GetMagneticField())<0.001) return;
470 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
471 AliInputEventHandler *inputHandler=(AliInputEventHandler*)mgr->GetInputEventHandler();
472 AliPIDResponse *pidResp=inputHandler->GetPIDResponse();
473 fPidHF->SetPidResponse(pidResp);
476 fHistNEvents->Fill(0); // count event
477 // Post the data already here
480 fCounter->StoreEvent(aod,fAnalysisCuts,fReadMC);
482 Bool_t isEvSel=fAnalysisCuts->IsEventSelected(aod);
483 if(fAnalysisCuts->IsEventRejectedDueToTrigger())fHistNEvents->Fill(2);
484 if(fAnalysisCuts->IsEventRejectedDueToNotRecoVertex())fHistNEvents->Fill(3);
485 if(fAnalysisCuts->IsEventRejectedDueToVertexContributors())fHistNEvents->Fill(4);
486 if(fAnalysisCuts->IsEventRejectedDueToZVertexOutsideFiducialRegion())fHistNEvents->Fill(5);
487 // if(fAnalysisCuts->IsEventRejectedDueToPileup())fHistNEvents->Fill(6);
488 if(fAnalysisCuts->IsEventRejectedDueToCentrality()) fHistNEvents->Fill(7);
492 fHistNEvents->Fill(1);
494 TClonesArray *arrayMC=0;
495 AliAODMCHeader *mcHeader=0;
497 arrayMC = (TClonesArray*)aod->GetList()->FindObject(AliAODMCParticle::StdBranchName());
499 printf("AliAnalysisTaskCombinHF::UserExec: MC particles branch not found!\n");
504 mcHeader = (AliAODMCHeader*)aod->GetList()->FindObject(AliAODMCHeader::StdBranchName());
506 printf("AliAnalysisTaskCombinHF::UserExec: MC header branch not found!\n");
509 FillGenHistos(arrayMC);
513 Int_t ntracks=aod->GetNTracks();
514 fVtxZ = aod->GetPrimaryVertex()->GetZ();
515 fMultiplicity = AliVertexingHFUtils::GetNumberOfTrackletsInEtaRange(aod,-1.,1.);
517 // select and flag tracks
518 UChar_t* status = new UChar_t[ntracks];
519 for(Int_t iTr=0; iTr<ntracks; iTr++){
521 AliAODTrack* track=aod->GetTrack(iTr);
522 if(IsTrackSelected(track)) status[iTr]+=1;
525 if (fPIDstrategy == knSigma) {
527 if(IsKaon(track)) status[iTr]+=2;
528 if(IsPion(track)) status[iTr]+=4;
530 else if (fPIDstrategy == kBayesianMaxProb || fPIDstrategy == kBayesianThres) {
532 Double_t *weights = new Double_t[AliPID::kSPECIES];
533 fPidHF->GetPidCombined()->ComputeProbabilities(track, fPidHF->GetPidResponse(), weights);
534 if (fPIDstrategy == kBayesianMaxProb) {
535 if (TMath::MaxElement(AliPID::kSPECIES, weights) == weights[AliPID::kKaon]) status[iTr] += 2;
536 if (TMath::MaxElement(AliPID::kSPECIES, weights) == weights[AliPID::kPion]) status[iTr] += 4;
538 if (fPIDstrategy == kBayesianThres) {
539 if (weights[AliPID::kKaon] > fBayesThresKaon) status[iTr] += 2;
540 if (weights[AliPID::kPion] > fBayesThresPion) status[iTr] += 4;
545 fHistTrackStatus->Fill(status[iTr]);
548 // build the combinatorics
551 Double_t dummypos[3]={0.,0.,0.};
552 AliAODVertex* v2=new AliAODVertex(dummypos,999.,-1,2);
553 AliAODVertex* v3=new AliAODVertex(dummypos,999.,-1,3);
554 // dummy values of track impact parameter, needed to build an AliAODRecoDecay object
555 Double_t d02[2]={0.,0.};
556 Double_t d03[3]={0.,0.,0.};
557 AliAODRecoDecay* tmpRD2 = new AliAODRecoDecay(0x0,2,0,d02);
558 AliAODRecoDecay* tmpRD3 = new AliAODRecoDecay(0x0,3,1,d03);
559 UInt_t pdg0[2]={321,211};
560 UInt_t pdgp[3]={321,211,211};
561 // UInt_t pdgs[3]={321,321,211};
563 Double_t px[3],py[3],pz[3];
565 fKaonTracks->Delete();
566 fPionTracks->Delete();
568 for(Int_t iTr1=0; iTr1<ntracks; iTr1++){
569 AliAODTrack* trK=aod->GetTrack(iTr1);
570 if((status[iTr1] & 1)==0) continue;
572 if(status[iTr1] & 2) fKaonTracks->AddLast(new TLorentzVector(trK->Px(),trK->Py(),trK->Pz(),trK->Charge()));
573 if(status[iTr1] & 4) fPionTracks->AddLast(new TLorentzVector(trK->Px(),trK->Py(),trK->Pz(),trK->Charge()));
575 if((status[iTr1] & 2)==0) continue;
576 Int_t chargeK=trK->Charge();
577 trK->GetPxPyPz(tmpp);
581 dgLabels[0]=trK->GetLabel();
582 for(Int_t iTr2=0; iTr2<ntracks; iTr2++){
583 if((status[iTr2] & 1)==0) continue;
584 if((status[iTr2] & 4)==0) continue;
585 if(iTr1==iTr2) continue;
586 AliAODTrack* trPi1=aod->GetTrack(iTr2);
587 Int_t chargePi1=trPi1->Charge();
588 trPi1->GetPxPyPz(tmpp);
592 dgLabels[1]=trPi1->GetLabel();
593 if(chargePi1==chargeK){
594 if(fMeson==kDzero) FillLSHistos(421,2,tmpRD2,px,py,pz,pdg0,chargePi1);
599 v2->AddDaughter(trK);
600 v2->AddDaughter(trPi1);
601 tmpRD2->SetSecondaryVtx(v2);
602 Bool_t ok=FillHistos(421,2,tmpRD2,px,py,pz,pdg0,arrayMC,dgLabels);
603 v2->RemoveDaughters();
606 for(Int_t iTr3=iTr2+1; iTr3<ntracks; iTr3++){
607 if((status[iTr3] & 1)==0) continue;
608 if((status[iTr3] & 4)==0) continue;
609 if(iTr1==iTr3) continue;
610 AliAODTrack* trPi2=aod->GetTrack(iTr3);
611 Int_t chargePi2=trPi2->Charge();
612 if(chargePi2==chargeK) continue;
614 trPi2->GetPxPyPz(tmpp);
618 dgLabels[2]=trPi2->GetLabel();
619 v3->AddDaughter(trK);
620 v3->AddDaughter(trPi1);
621 v3->AddDaughter(trPi2);
622 tmpRD3->SetSecondaryVtx(v3);
623 Bool_t ok=FillHistos(411,3,tmpRD3,px,py,pz,pdgp,arrayMC,dgLabels);
624 v3->RemoveDaughters();
637 fNSelected->Fill(nSelected);
639 fCounter->StoreCandidates(aod,nFiltered,kTRUE);
640 fCounter->StoreCandidates(aod,nSelected,kFALSE);
642 if(fDoEventMixing) fEventBuffer->Fill();
644 PostData(2,fCounter);
649 //________________________________________________________________________
650 void AliAnalysisTaskCombinHF::FillLSHistos(Int_t pdgD,Int_t nProngs, AliAODRecoDecay* tmpRD, Double_t* px, Double_t* py, Double_t* pz, UInt_t *pdgdau, Int_t charge){
651 // Fill histos for LS candidates
653 tmpRD->SetPxPyPzProngs(nProngs,px,py,pz);
654 Double_t pt = tmpRD->Pt();
655 Double_t minv2 = tmpRD->InvMass2(nProngs,pdgdau);
656 if(minv2>fMinMass*fMinMass && minv2<fMaxMass*fMaxMass){
657 Double_t rapid = tmpRD->Y(pdgD);
658 if(fAnalysisCuts->IsInFiducialAcceptance(pt,rapid)){
659 if(charge>0) fMassVsPtVsYLSpp->Fill(TMath::Sqrt(minv2),pt,rapid);
660 else fMassVsPtVsYLSmm->Fill(TMath::Sqrt(minv2),pt,rapid);
666 //________________________________________________________________________
667 void AliAnalysisTaskCombinHF::FillGenHistos(TClonesArray* arrayMC){
668 // Fill histos with generated quantities
669 Int_t totPart=arrayMC->GetEntriesFast();
676 for(Int_t ip=0; ip<totPart; ip++){
677 AliAODMCParticle *part = (AliAODMCParticle*)arrayMC->At(ip);
678 if(TMath::Abs(part->GetPdgCode())==thePDG){
679 Int_t orig=AliVertexingHFUtils::CheckOrigin(arrayMC,part,fGoUpToQuark);
680 fHistCheckOrigin->Fill(orig);
681 if(fPromptFeeddown==kFeeddown && orig!=5) continue;
682 else if(fPromptFeeddown==kPrompt && orig!=4) continue;
683 else if(fPromptFeeddown==kBoth && orig<4) continue;
684 fHistCheckOriginSel->Fill(orig);
686 Bool_t isGoodDecay=kFALSE;
687 Int_t labDau[4]={-1,-1,-1,-1};
689 deca=AliVertexingHFUtils::CheckD0Decay(arrayMC,part,labDau);
690 if(part->GetNDaughters()!=2) continue;
691 if(deca==1) isGoodDecay=kTRUE;
692 }else if(fMeson==kDplus){
693 deca=AliVertexingHFUtils::CheckDplusDecay(arrayMC,part,labDau);
694 if(deca>0) isGoodDecay=kTRUE;
696 fHistCheckDecChan->Fill(deca);
698 // printf(Form("Meson %d Label of daughters not filled correctly -- %d\n",fMeson,isGoodDecay));
699 continue; //protection against unfilled array of labels
701 Bool_t isInAcc=CheckAcceptance(arrayMC,nProng,labDau);
702 if(isInAcc) fHistCheckDecChanAcc->Fill(deca);
704 Double_t ptgen=part->Pt();
705 Double_t ygen=part->Y();
706 if(fAnalysisCuts->IsInFiducialAcceptance(ptgen,ygen)){
707 fPtVsYGen->Fill(ptgen,ygen);
708 if(TMath::Abs(ygen)<0.5) fPtVsYGenLimAcc->Fill(ptgen,ygen);
709 if(isInAcc) fPtVsYGenAcc->Fill(ptgen,ygen);
711 if(TMath::Abs(ygen)<0.9) fPtVsYGenLargeAcc->Fill(ptgen,ygen);
717 //________________________________________________________________________
718 Bool_t AliAnalysisTaskCombinHF::FillHistos(Int_t pdgD,Int_t nProngs, AliAODRecoDecay* tmpRD, Double_t* px, Double_t* py, Double_t* pz, UInt_t *pdgdau, TClonesArray *arrayMC, Int_t* dgLabels){
719 // Fill histos for candidates with proper charge sign
721 Bool_t accept=kFALSE;
723 tmpRD->SetPxPyPzProngs(nProngs,px,py,pz);
724 Double_t pt = tmpRD->Pt();
725 Double_t minv2 = tmpRD->InvMass2(nProngs,pdgdau);
726 Double_t mass=TMath::Sqrt(minv2);
728 if(minv2>fMinMass*fMinMass && minv2<fMaxMass*fMaxMass){
729 Double_t rapid = tmpRD->Y(pdgD);
730 if(fAnalysisCuts->IsInFiducialAcceptance(pt,rapid)){
731 fMassVsPtVsY->Fill(mass,pt,rapid);
734 Int_t signPdg[3]={0,0,0};
735 for(Int_t iii=0; iii<nProngs; iii++) signPdg[iii]=pdgdau[iii];
736 Int_t labD = tmpRD->MatchToMC(pdgD,arrayMC,nProngs,signPdg);
738 AliAODMCParticle* part = dynamic_cast<AliAODMCParticle*>(arrayMC->At(TMath::Abs(dgLabels[0])));
740 Int_t orig=AliVertexingHFUtils::CheckOrigin(arrayMC,part,fGoUpToQuark);
741 if((fPromptFeeddown==kFeeddown && orig==5)|| (fPromptFeeddown==kPrompt && orig==4) || (fPromptFeeddown==kBoth && orig>=4)) {
743 Int_t pdgCode = TMath::Abs( part->GetPdgCode() );
745 fMassVsPtVsYSig->Fill(mass,pt,rapid);
746 AliAODMCParticle* dmes = dynamic_cast<AliAODMCParticle*>(arrayMC->At(labD));
747 fPtVsYReco->Fill(dmes->Pt(),dmes->Y());
749 fMassVsPtVsYRefl->Fill(mass,pt,rapid);
754 fMassVsPtVsYBkg->Fill(mass,pt,rapid);
761 Double_t massRot=0;// calculated later only if candidate is acceptable
762 Double_t angleProngXY;
763 if(TMath::Abs(pdgD)==421)angleProngXY=TMath::ACos((px[0]*px[1]+py[0]*py[1])/TMath::Sqrt((px[0]*px[0]+py[0]*py[0])*(px[1]*px[1]+py[1]*py[1])));
765 angleProngXY=TMath::ACos(((px[0]+px[1])*px[2]+(py[0]+py[1])*py[2])/TMath::Sqrt(((px[0]+px[1])*(px[0]+px[1])+(py[0]+py[1])*(py[0]+py[1]))*(px[2]*px[2]+py[2]*py[2])));
770 Double_t rotStep=(fMaxAngleForRot-fMinAngleForRot)/(fNRotations-1); // -1 is to ensure that the last rotation is done with angle=fMaxAngleForRot
771 Double_t rotStep3=(fMaxAngleForRot3-fMinAngleForRot3)/(fNRotations-1); // -1 is to ensure that the last rotation is done with angle=fMaxAngleForRot
773 for(Int_t irot=0; irot<fNRotations; irot++){
774 Double_t phirot=fMinAngleForRot+rotStep*irot;
777 Double_t tmpx2=px[2];
778 Double_t tmpy2=py[2];
779 px[0]=tmpx*TMath::Cos(phirot)-tmpy*TMath::Sin(phirot);
780 py[0]=tmpx*TMath::Sin(phirot)+tmpy*TMath::Cos(phirot);
781 if(pdgD==411 || pdgD==431){
782 Double_t phirot2=fMinAngleForRot3+rotStep3*irot;
783 px[2]=tmpx*TMath::Cos(phirot2)-tmpy*TMath::Sin(phirot2);
784 py[2]=tmpx*TMath::Sin(phirot2)+tmpy*TMath::Cos(phirot2);
786 tmpRD->SetPxPyPzProngs(nProngs,px,py,pz);
788 minv2 = tmpRD->InvMass2(nProngs,pdgdau);
789 if(minv2>fMinMass*fMinMass && minv2<fMaxMass*fMaxMass){
790 Double_t rapid = tmpRD->Y(pdgD);
791 if(fAnalysisCuts->IsInFiducialAcceptance(pt,rapid)){
792 massRot=TMath::Sqrt(minv2);
793 fMassVsPtVsYRot->Fill(massRot,pt,rapid);
795 fDeltaMass->Fill(massRot-mass);
797 Double_t pointRot[5]={mass,massRot-mass,ptOrig,pt-ptOrig,angleProngXY};
798 fDeltaMassFullAnalysis->Fill(pointRot);
804 if(pdgD==411 || pdgD==431){
809 fNormRotated->Fill(nRotated);
814 //________________________________________________________________________
815 void AliAnalysisTaskCombinHF::FillMEHistos(Int_t pdgD,Int_t nProngs, AliAODRecoDecay* tmpRD, Double_t* px, Double_t* py, Double_t* pz, UInt_t *pdgdau){
816 // Fill histos for candidates in MixedEvents
818 tmpRD->SetPxPyPzProngs(nProngs,px,py,pz);
819 Double_t pt = tmpRD->Pt();
820 Double_t minv2 = tmpRD->InvMass2(nProngs,pdgdau);
821 Double_t mass=TMath::Sqrt(minv2);
823 if(minv2>fMinMass*fMinMass && minv2<fMaxMass*fMaxMass){
824 Double_t rapid = tmpRD->Y(pdgD);
825 if(fAnalysisCuts->IsInFiducialAcceptance(pt,rapid)){
826 fMassVsPtVsYME->Fill(mass,pt,rapid);
832 //________________________________________________________________________
833 Bool_t AliAnalysisTaskCombinHF::IsTrackSelected(AliAODTrack* track){
834 // track selection cuts
836 if(track->Charge()==0) return kFALSE;
837 if(track->GetID()<0&&!fKeepNegID)return kFALSE;
838 if(!(track->TestFilterMask(fFilterMask))) return kFALSE;
839 if(!SelectAODTrack(track,fTrackCutsAll)) return kFALSE;
843 //________________________________________________________________________
844 Bool_t AliAnalysisTaskCombinHF::IsKaon(AliAODTrack* track){
845 // kaon selection cuts
847 if(!fPidHF) return kTRUE;
848 Int_t isKaon=fPidHF->MakeRawPid(track,AliPID::kKaon);
849 Double_t mom=track->P();
850 if(SelectAODTrack(track,fTrackCutsKaon)) {
851 if(isKaon>=1) return kTRUE;
852 if(isKaon<=-1) return kFALSE;
853 switch(fPIDselCaseZero){// isKaon=0
856 return kTRUE;// always accept
861 if(isKaon>=0 && track->P()>fmaxPforIDKaon)return kTRUE;// accept only if in a compatibility band starting from p=fmaxPforIDKaon
866 if(track->P()>fmaxPforIDKaon)return kTRUE;
867 AliPIDResponse *pidResp=fPidHF->GetPidResponse();// more elaborated strategy: asymmetric cuts, with fix momenta and nsigma ranges for the moment
868 Double_t nsigma=pidResp->NumberOfSigmasTPC(track,AliPID::kKaon);
869 if(nsigma>-2.&& nsigma<3. && mom<0.6)isKaon=1;
870 else if(nsigma>-1.&& nsigma<3.&& mom<0.8)isKaon=1;
871 if(isKaon==1)return kTRUE;
876 AliWarning(Form("WRONG CASE OF PID STRATEGY SELECTED: %d (can range from 0 to 2)",fPIDselCaseZero));
877 return kFALSE;// actually case 0 could be set as the default and return kTRUE
884 //_______________________________________________________________________
885 Bool_t AliAnalysisTaskCombinHF::IsPion(AliAODTrack* track){
886 // pion selection cuts
888 if(!fPidHF) return kTRUE;
889 Int_t isPion=fPidHF->MakeRawPid(track,AliPID::kPion);
890 Double_t mom=track->P();
891 if(SelectAODTrack(track,fTrackCutsPion)) {
892 if(isPion>=1) return kTRUE;
893 if(isPion<=-1) return kFALSE;
894 switch(fPIDselCaseZero){// isPion=0
897 return kTRUE;// always accept
902 if(track->P()>fmaxPforIDPion)return kTRUE;// accept only if in a compatibility band starting from p=fmaxPforIDPion
907 // more elaborated strategy: asymmetric cuts, with fix momenta and nsigma ranges for the moment
908 if(track->P()>fmaxPforIDPion)return kTRUE;
909 AliPIDResponse *pidResp=fPidHF->GetPidResponse();
910 Double_t nsigma=pidResp->NumberOfSigmasTPC(track,AliPID::kPion);
911 if(nsigma<2.&& nsigma>-3. && mom<0.6)isPion=1;
912 else if(nsigma<1. && nsigma> -3. && mom<0.8)isPion=1;
913 if(isPion==1)return kTRUE;
918 AliWarning(Form("WRONG CASE OF PID STRATEGY SELECTED: %d (can range from 0 to 2)",fPIDselCaseZero));
919 return kFALSE;// actually case 0 could be set as the default and return kTRUE
927 //________________________________________________________________________
928 Bool_t AliAnalysisTaskCombinHF::SelectAODTrack(AliAODTrack *track, AliESDtrackCuts *cuts){
929 // AOD track selection
931 if(!cuts) return kTRUE;
933 AliESDtrack esdTrack(track);
934 // set the TPC cluster info
935 esdTrack.SetTPCClusterMap(track->GetTPCClusterMap());
936 esdTrack.SetTPCSharedMap(track->GetTPCSharedMap());
937 esdTrack.SetTPCPointsF(track->GetTPCNclsF());
938 if(!cuts->IsSelected(&esdTrack)) return kFALSE;
943 //_________________________________________________________________
944 Bool_t AliAnalysisTaskCombinHF::CheckAcceptance(TClonesArray* arrayMC,Int_t nProng, Int_t *labDau){
945 // check if the decay products are in the good eta and pt range
946 for (Int_t iProng = 0; iProng<nProng; iProng++){
947 AliAODMCParticle* mcPartDaughter=dynamic_cast<AliAODMCParticle*>(arrayMC->At(labDau[iProng]));
948 if(!mcPartDaughter) return kFALSE;
949 Double_t eta = mcPartDaughter->Eta();
950 Double_t pt = mcPartDaughter->Pt();
951 if (TMath::Abs(eta) > fEtaAccCut || pt < fPtAccCut) return kFALSE;
955 //_________________________________________________________________
956 Bool_t AliAnalysisTaskCombinHF::CanBeMixed(Double_t zv1, Double_t zv2, Double_t mult1, Double_t mult2){
957 if(fUsePoolsZ && fzVertPoolLims){
958 Int_t theBin1=TMath::BinarySearch(fNzVertPoolsLimSize,fzVertPoolLims,zv1);
959 Int_t theBin2=TMath::BinarySearch(fNzVertPoolsLimSize,fzVertPoolLims,zv2);
960 if(theBin1!=theBin2) return kFALSE;
961 if(theBin1<0 || theBin2<0) return kFALSE;
962 if(theBin1>=fNzVertPools || theBin2>=fNzVertPools) return kFALSE;
964 if(TMath::Abs(zv2-zv1)>fMaxzVertDistForMix) return kFALSE;
967 if(fUsePoolsM && fMultPoolLims){
968 Int_t theBin1=TMath::BinarySearch(fNMultPoolsLimSize,fMultPoolLims,mult1);
969 Int_t theBin2=TMath::BinarySearch(fNMultPoolsLimSize,fMultPoolLims,mult2);
970 if(theBin1!=theBin2) return kFALSE;
971 if(theBin1<0 || theBin2<0) return kFALSE;
972 if(theBin1>=fNMultPools || theBin2>=fNMultPools) return kFALSE;
974 if(TMath::Abs(mult2-mult1)>fMaxMultDiffForMix) return kFALSE;
979 //_________________________________________________________________
980 void AliAnalysisTaskCombinHF::FinishTaskOutput()
982 // perform mixed event analysis
983 if(!fDoEventMixing) return;
985 Int_t nEvents=fEventBuffer->GetEntries();
986 printf("Start Event Mixing of %d events\n",nEvents);
988 TObjArray* karray=0x0;
989 TObjArray* parray=0x0;
990 Double_t zVertex,mult;
991 fEventBuffer->SetBranchAddress("karray", &karray);
992 fEventBuffer->SetBranchAddress("parray", &parray);
993 fEventBuffer->SetBranchAddress("zVertex", &zVertex);
994 fEventBuffer->SetBranchAddress("multiplicity", &mult);
996 // dummy values of track impact parameter, needed to build an AliAODRecoDecay object
997 Double_t d02[2]={0.,0.};
998 Double_t d03[3]={0.,0.,0.};
999 AliAODRecoDecay* tmpRD2 = new AliAODRecoDecay(0x0,2,0,d02);
1000 AliAODRecoDecay* tmpRD3 = new AliAODRecoDecay(0x0,3,1,d03);
1001 UInt_t pdg0[2]={321,211};
1002 UInt_t pdgp[3]={321,211,211};
1003 Double_t px[3],py[3],pz[3];
1005 for(Int_t iEv1=0; iEv1<nEvents; iEv1++){
1006 fEventBuffer->GetEvent(iEv1);
1007 Double_t zVertex1=zVertex;
1008 Double_t mult1=mult;
1009 TObjArray* karray1=new TObjArray(*karray);
1010 for(Int_t iEv2=0; iEv2<fMaxNumberOfEventsForMixing; iEv2++){
1011 Int_t iToMix=iEv1+iEv2+1;
1012 if(iEv1>=(nEvents-fMaxNumberOfEventsForMixing)) iToMix=iEv1-iEv2-1;
1013 if(iToMix<0) continue;
1014 if(iToMix==iEv1) continue;
1015 fEventBuffer->GetEvent(iToMix);
1016 Double_t zVertex2=zVertex;
1017 Double_t mult2=mult;
1018 if(CanBeMixed(zVertex1,zVertex2,mult1,mult2)){
1019 TObjArray* parray2=new TObjArray(*parray);
1020 Int_t nKaons=karray1->GetEntries();
1021 Int_t nPions=parray2->GetEntries();
1022 Bool_t doThird=kTRUE;
1023 Int_t iToMix3=iEv1+2*fMaxNumberOfEventsForMixing+1;
1024 if(iToMix3>=nEvents) iToMix3=iEv1-2*fMaxNumberOfEventsForMixing-1;
1025 if(iToMix3<0 || iToMix3==iEv1 || iToMix3==iToMix) doThird=kFALSE;
1026 TObjArray* parray3=0x0;
1027 Double_t zVertex3=-999.;
1028 Double_t mult3=999999;
1029 if(fMeson!=kDzero && doThird){
1030 fEventBuffer->GetEvent(iToMix3);
1033 if(CanBeMixed(zVertex1,zVertex3,mult1,mult3)){
1034 parray3=new TObjArray(*parray);
1040 for(Int_t iTr1=0; iTr1<nKaons; iTr1++){
1041 TLorentzVector* trK=(TLorentzVector*)karray1->At(iTr1);
1042 Double_t chargeK=trK->T();
1046 for(Int_t iTr2=0; iTr2<nPions; iTr2++){
1047 TLorentzVector* trPi1=(TLorentzVector*)parray2->At(iTr2);
1048 Double_t chargePi1=trPi1->T();
1049 px[1] = trPi1->Px();
1050 py[1] = trPi1->Py();
1051 pz[1] = trPi1->Pz();
1052 if(chargePi1*chargeK<0){
1054 FillMEHistos(421,2,tmpRD2,px,py,pz,pdg0);
1056 if(doThird && parray3){
1057 Int_t nPions3=parray3->GetEntries();
1058 for(Int_t iTr3=iTr2+1; iTr3<nPions3; iTr3++){
1059 TLorentzVector* trPi2=(TLorentzVector*)parray3->At(iTr3);
1060 Double_t chargePi2=trPi2->T();
1061 px[2] = trPi2->Px();
1062 py[2] = trPi2->Py();
1063 pz[2] = trPi2->Pz();
1064 if(chargePi2*chargeK<0){
1065 FillMEHistos(411,3,tmpRD3,px,py,pz,pdgp);
1082 //_________________________________________________________________
1083 void AliAnalysisTaskCombinHF::Terminate(Option_t */*option*/)
1085 // Terminate analysis
1087 if(fDebug > 1) printf("AliAnalysisTaskCombinHF: Terminate() \n");
1088 fOutput = dynamic_cast<TList*> (GetOutputData(1));
1090 printf("ERROR: fOutput not available\n");
1093 fHistNEvents = dynamic_cast<TH1F*>(fOutput->FindObject("hNEvents"));
1095 printf("Number of analyzed events = %d\n",(Int_t)fHistNEvents->GetBinContent(2));
1097 printf("ERROR: fHistNEvents not available\n");