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),
73 fMassVsPtVsYMELSpp(0x0),
74 fMassVsPtVsYMELSmm(0x0),
81 fPidHF(new AliAODPidHF()),
90 fMinAngleForRot(5*TMath::Pi()/6),
91 fMaxAngleForRot(7*TMath::Pi()/6),
92 fMinAngleForRot3(2*TMath::Pi()/6),
93 fMaxAngleForRot3(4*TMath::Pi()/6),
97 fPromptFeeddown(kPrompt),
100 fPIDstrategy(knSigma),
105 fBayesThresKaon(0.4),
106 fBayesThresPion(0.4),
108 fNumberOfEventsForMixing(20),
109 fMaxzVertDistForMix(5.),
110 fMaxMultDiffForMix(5.),
112 fNzVertPoolsLimSize(2),
115 fNMultPoolsLimSize(2),
119 fEventInfo(new TObjString("")),
125 // default constructor
128 //________________________________________________________________________
129 AliAnalysisTaskCombinHF::AliAnalysisTaskCombinHF(Int_t meson, AliRDHFCuts* analysiscuts):
130 AliAnalysisTaskSE("DmesonCombin"),
133 fHistTrackStatus(0x0),
134 fHistCheckOrigin(0x0),
135 fHistCheckOriginSel(0x0),
136 fHistCheckDecChan(0x0),
137 fHistCheckDecChanAcc(0x0),
139 fPtVsYGenLargeAcc(0x0),
140 fPtVsYGenLimAcc(0x0),
144 fMassVsPtVsYRot(0x0),
145 fMassVsPtVsYLSpp(0x0),
146 fMassVsPtVsYLSmm(0x0),
147 fMassVsPtVsYSig(0x0),
148 fMassVsPtVsYRefl(0x0),
149 fMassVsPtVsYBkg(0x0),
153 fDeltaMassFullAnalysis(0x0),
155 fMassVsPtVsYMELSpp(0x0),
156 fMassVsPtVsYMELSmm(0x0),
158 fMixingsPerPool(0x0),
163 fPidHF(new AliAODPidHF()),
164 fAnalysisCuts(analysiscuts),
172 fMinAngleForRot(5*TMath::Pi()/6),
173 fMaxAngleForRot(7*TMath::Pi()/6),
174 fMinAngleForRot3(2*TMath::Pi()/6),
175 fMaxAngleForRot3(4*TMath::Pi()/6),
182 fPIDstrategy(knSigma),
187 fBayesThresKaon(0.4),
188 fBayesThresPion(0.4),
190 fNumberOfEventsForMixing(20),
191 fMaxzVertDistForMix(5.),
192 fMaxMultDiffForMix(5.),
194 fNzVertPoolsLimSize(2),
197 fNMultPoolsLimSize(2),
201 fEventInfo(new TObjString("")),
207 // standard constructor
209 DefineOutput(1,TList::Class()); //My private output
210 DefineOutput(2,AliNormalizationCounter::Class());
213 //________________________________________________________________________
214 AliAnalysisTaskCombinHF::~AliAnalysisTaskCombinHF()
219 if(fOutput && !fOutput->IsOwner()){
221 delete fHistTrackStatus;
222 delete fHistCheckOrigin;
223 delete fHistCheckOriginSel;
224 delete fHistCheckDecChan;
225 delete fHistCheckDecChanAcc;
227 delete fPtVsYGenLargeAcc;
228 delete fPtVsYGenLimAcc;
232 delete fMassVsPtVsYLSpp;
233 delete fMassVsPtVsYLSmm;
234 delete fMassVsPtVsYRot;
235 delete fMassVsPtVsYSig;
236 delete fMassVsPtVsYRefl;
237 delete fMassVsPtVsYBkg;
241 delete fDeltaMassFullAnalysis;
242 delete fMassVsPtVsYME;
243 delete fMassVsPtVsYMELSpp;
244 delete fMassVsPtVsYMELSmm;
249 delete fTrackCutsAll;
250 delete fTrackCutsPion;
251 delete fTrackCutsKaon;
253 delete fAnalysisCuts;
254 if(fKaonTracks) fKaonTracks->Delete();
255 if(fPionTracks) fPionTracks->Delete();
260 for(Int_t i=0; i<fNOfPools; i++) delete fEventBuffer[i];
264 delete [] fzVertPoolLims;
265 delete [] fMultPoolLims;
268 //________________________________________________________________________
269 void AliAnalysisTaskCombinHF::ConfigureZVertPools(Int_t nPools, Double_t* zVertLimits)
271 // sets the pools for event mizing in zvertex
272 if(fzVertPoolLims) delete [] fzVertPoolLims;
274 fNzVertPoolsLimSize=nPools+1;
275 fzVertPoolLims = new Double_t[fNzVertPoolsLimSize];
276 for(Int_t ib=0; ib<fNzVertPoolsLimSize; ib++) fzVertPoolLims[ib]=zVertLimits[ib];
279 //________________________________________________________________________
280 void AliAnalysisTaskCombinHF::ConfigureMultiplicityPools(Int_t nPools, Double_t* multLimits)
282 // sets the pools for event mizing in zvertex
283 if(fMultPoolLims) delete [] fMultPoolLims;
285 fNMultPoolsLimSize=nPools+1;
286 fMultPoolLims = new Double_t[fNMultPoolsLimSize];
287 for(Int_t ib=0; ib<nPools+1; ib++) fMultPoolLims[ib]=multLimits[ib];
290 //________________________________________________________________________
291 void AliAnalysisTaskCombinHF::UserCreateOutputObjects()
293 // Create the output container
295 if(fDebug > 1) printf("AnalysisTaskCombinHF::UserCreateOutputObjects() \n");
297 fOutput = new TList();
299 fOutput->SetName("OutputHistos");
301 fHistNEvents = new TH1F("hNEvents", "number of events ",8,-0.5,7.5);
302 fHistNEvents->GetXaxis()->SetBinLabel(1,"nEventsAnal");
303 fHistNEvents->GetXaxis()->SetBinLabel(2,"n. passing IsEvSelected");
304 fHistNEvents->GetXaxis()->SetBinLabel(3,"n. rejected due to trigger");
305 fHistNEvents->GetXaxis()->SetBinLabel(4,"n. rejected due to not reco vertex");
306 fHistNEvents->GetXaxis()->SetBinLabel(5,"n. rejected for contr vertex");
307 fHistNEvents->GetXaxis()->SetBinLabel(6,"n. rejected for vertex out of accept");
308 fHistNEvents->GetXaxis()->SetBinLabel(7,"n. rejected for pileup events");
309 fHistNEvents->GetXaxis()->SetBinLabel(8,"no. of out centrality events");
311 fHistNEvents->GetXaxis()->SetNdivisions(1,kFALSE);
312 fHistNEvents->Sumw2();
313 fHistNEvents->SetMinimum(0);
314 fOutput->Add(fHistNEvents);
316 fHistTrackStatus = new TH1F("hTrackStatus", "",8,-0.5,7.5);
317 fHistTrackStatus->GetXaxis()->SetBinLabel(1,"Not OK");
318 fHistTrackStatus->GetXaxis()->SetBinLabel(2,"Track OK");
319 fHistTrackStatus->GetXaxis()->SetBinLabel(3,"Kaon, Not OK");
320 fHistTrackStatus->GetXaxis()->SetBinLabel(4,"Kaon OK");
321 fHistTrackStatus->GetXaxis()->SetBinLabel(5,"Pion, Not OK");
322 fHistTrackStatus->GetXaxis()->SetBinLabel(6,"Pion OK");
323 fHistTrackStatus->GetXaxis()->SetBinLabel(7,"Kaon||Pion, Not OK");
324 fHistTrackStatus->GetXaxis()->SetBinLabel(8,"Kaon||Pion OK");
325 fHistTrackStatus->GetXaxis()->SetNdivisions(1,kFALSE);
326 fHistTrackStatus->Sumw2();
327 fHistTrackStatus->SetMinimum(0);
328 fOutput->Add(fHistTrackStatus);
330 Int_t nPtBins = (Int_t)(fMaxPt/fPtBinWidth+0.001);
331 Double_t maxPt=fPtBinWidth*nPtBins;
335 fHistCheckOrigin=new TH1F("hCheckOrigin","",7,-1.5,5.5);
336 fHistCheckOrigin->Sumw2();
337 fHistCheckOrigin->SetMinimum(0);
338 fOutput->Add(fHistCheckOrigin);
340 fHistCheckOriginSel=new TH1F("hCheckOriginSel","",7,-1.5,5.5);
341 fHistCheckOriginSel->Sumw2();
342 fHistCheckOriginSel->SetMinimum(0);
343 fOutput->Add(fHistCheckOriginSel);
345 fHistCheckDecChan=new TH1F("hCheckDecChan","",7,-2.5,4.5);
346 fHistCheckDecChan->Sumw2();
347 fHistCheckDecChan->SetMinimum(0);
348 fOutput->Add(fHistCheckDecChan);
350 fHistCheckDecChanAcc=new TH1F("hCheckDecChanAcc","",7,-2.5,4.5);
351 fHistCheckDecChanAcc->Sumw2();
352 fHistCheckDecChanAcc->SetMinimum(0);
353 fOutput->Add(fHistCheckDecChanAcc);
355 fPtVsYGen= new TH2F("hPtVsYGen","",nPtBins,0.,maxPt,20,-1.,1.);
357 fPtVsYGen->SetMinimum(0);
358 fOutput->Add(fPtVsYGen);
360 fPtVsYGenLargeAcc= new TH2F("hPtVsYGenLargeAcc","",nPtBins,0.,maxPt,20,-1.,1.);
361 fPtVsYGenLargeAcc->Sumw2();
362 fPtVsYGenLargeAcc->SetMinimum(0);
363 fOutput->Add(fPtVsYGenLargeAcc);
365 fPtVsYGenLimAcc= new TH2F("hPtVsYGenLimAcc","",nPtBins,0.,maxPt,20,-1.,1.);
366 fPtVsYGenLimAcc->Sumw2();
367 fPtVsYGenLimAcc->SetMinimum(0);
368 fOutput->Add(fPtVsYGenLimAcc);
370 fPtVsYGenAcc= new TH2F("hPtVsYGenAcc","",nPtBins,0.,maxPt,20,-1.,1.);
371 fPtVsYGenAcc->Sumw2();
372 fPtVsYGenAcc->SetMinimum(0);
373 fOutput->Add(fPtVsYGenAcc);
375 fPtVsYReco= new TH2F("hPtVsYReco","",nPtBins,0.,maxPt,20,-1.,1.);
377 fPtVsYReco->SetMinimum(0);
378 fOutput->Add(fPtVsYReco);
382 Int_t nMassBins=static_cast<Int_t>(fMaxMass*1000.-fMinMass*1000.);
383 Double_t maxm=fMinMass+nMassBins*0.001;
384 fMassVsPtVsY=new TH3F("hMassVsPtVsY","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
385 fMassVsPtVsY->Sumw2();
386 fMassVsPtVsY->SetMinimum(0);
387 fOutput->Add(fMassVsPtVsY);
389 fMassVsPtVsYRot=new TH3F("hMassVsPtVsYRot","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
390 fMassVsPtVsYRot->Sumw2();
391 fMassVsPtVsYRot->SetMinimum(0);
392 fOutput->Add(fMassVsPtVsYRot);
395 fMassVsPtVsYLSpp=new TH3F("hMassVsPtVsYLSpp","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
396 fMassVsPtVsYLSpp->Sumw2();
397 fMassVsPtVsYLSpp->SetMinimum(0);
398 fOutput->Add(fMassVsPtVsYLSpp);
399 fMassVsPtVsYLSmm=new TH3F("hMassVsPtVsYLSmm","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
400 fMassVsPtVsYLSmm->Sumw2();
401 fMassVsPtVsYLSmm->SetMinimum(0);
402 fOutput->Add(fMassVsPtVsYLSmm);
405 fMassVsPtVsYSig=new TH3F("hMassVsPtVsYSig","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
406 fMassVsPtVsYSig->Sumw2();
407 fMassVsPtVsYSig->SetMinimum(0);
408 fOutput->Add(fMassVsPtVsYSig);
410 fMassVsPtVsYRefl=new TH3F("hMassVsPtVsYRefl","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
411 fMassVsPtVsYRefl->Sumw2();
412 fMassVsPtVsYRefl->SetMinimum(0);
413 fOutput->Add(fMassVsPtVsYRefl);
415 fMassVsPtVsYBkg=new TH3F("hMassVsPtVsYBkg","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
416 fMassVsPtVsYBkg->Sumw2();
417 fMassVsPtVsYBkg->SetMinimum(0);
418 fOutput->Add(fMassVsPtVsYBkg);
420 fNSelected=new TH1F("hNSelected","",100,-0.5,99.5);
422 fNSelected->SetMinimum(0);
423 fOutput->Add(fNSelected);
425 fNormRotated=new TH1F("hNormRotated","",11,-0.5,10.5);
426 fNormRotated->Sumw2();
427 fNormRotated->SetMinimum(0);
428 fOutput->Add(fNormRotated);
430 fDeltaMass=new TH1F("hDeltaMass","",100,-0.4,0.4);
432 fDeltaMass->SetMinimum(0);
433 fOutput->Add(fDeltaMass);
435 Int_t binSparseDMassRot[5]={nMassBins,100,24,40,20};
436 Double_t edgeLowSparseDMassRot[5]={fMinMass,-0.4,0.,-4.,0};
437 Double_t edgeHighSparseDMassRot[5]={maxm,0.4,12.,4.,3.14};
438 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);
439 fOutput->Add(fDeltaMassFullAnalysis);
441 fMassVsPtVsYME=new TH3F("hMassVsPtVsYME","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
442 fMassVsPtVsYME->Sumw2();
443 fMassVsPtVsYME->SetMinimum(0);
444 fOutput->Add(fMassVsPtVsYME);
446 fMassVsPtVsYMELSpp=new TH3F("hMassVsPtVsYMELSpp","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
447 fMassVsPtVsYMELSpp->Sumw2();
448 fMassVsPtVsYMELSpp->SetMinimum(0);
449 fOutput->Add(fMassVsPtVsYMELSpp);
451 fMassVsPtVsYMELSmm=new TH3F("hMassVsPtVsYMELSmm","",nMassBins,fMinMass,maxm,nPtBins,0.,maxPt,20,-1.,1.);
452 fMassVsPtVsYMELSmm->Sumw2();
453 fMassVsPtVsYMELSmm->SetMinimum(0);
454 fOutput->Add(fMassVsPtVsYMELSmm);
456 fNOfPools=fNzVertPools*fNMultPools;
457 if(!fzVertPoolLims || !fMultPoolLims) fNOfPools=1;
458 if(fDoEventMixing==2) fNOfPools=1;
459 if(fNOfPools>1 && fzVertPoolLims && fMultPoolLims){
460 fEventsPerPool=new TH2F("hEventsPerPool","hEventsPerPool",fNzVertPools,fzVertPoolLims,fNMultPools,fMultPoolLims);
461 fMixingsPerPool=new TH2F("hMixingsPerPool","hMixingsPerPool",fNzVertPools,fzVertPoolLims,fNMultPools,fMultPoolLims);
463 fEventsPerPool=new TH2F("hEventsPerPool","hEventsPerPool",1,-10.,10.,1,-0.5,2000.5);
464 fMixingsPerPool=new TH2F("hMixingsPerPool","hMixingsPerPool",1,-10.,10.,1,-0.5,2000.5);
466 fEventsPerPool->Sumw2();
467 fEventsPerPool->SetMinimum(0);
468 fOutput->Add(fEventsPerPool);
469 fMixingsPerPool->Sumw2();
470 fMixingsPerPool->SetMinimum(0);
471 fOutput->Add(fMixingsPerPool);
473 //Counter for Normalization
474 fCounter = new AliNormalizationCounter("NormalizationCounter");
477 fKaonTracks = new TObjArray();
478 fPionTracks=new TObjArray();
479 fKaonTracks->SetOwner();
480 fPionTracks->SetOwner();
482 fEventBuffer = new TTree*[fNOfPools];
483 for(Int_t i=0; i<fNOfPools; i++){
484 fEventBuffer[i]=new TTree(Form("EventBuffer_%d",i), "Temporary buffer for event mixing");
485 fEventBuffer[i]->Branch("zVertex", &fVtxZ);
486 fEventBuffer[i]->Branch("multiplicity", &fMultiplicity);
487 fEventBuffer[i]->Branch("eventInfo", "TObjString",&fEventInfo);
488 fEventBuffer[i]->Branch("karray", "TObjArray", &fKaonTracks);
489 fEventBuffer[i]->Branch("parray", "TObjArray", &fPionTracks);
493 PostData(2,fCounter);
496 //________________________________________________________________________
497 void AliAnalysisTaskCombinHF::UserExec(Option_t */*option*/){
498 //Build the 3-track combinatorics (+-+ and -+-) for D+->Kpipi decays
500 AliAODEvent *aod = dynamic_cast<AliAODEvent*> (InputEvent());
501 if(!aod && AODEvent() && IsStandardAOD()) {
502 // In case there is an AOD handler writing a standard AOD, use the AOD
503 // event in memory rather than the input (ESD) event.
504 aod = dynamic_cast<AliAODEvent*> (AODEvent());
507 printf("AliAnalysisTaskCombinHF::UserExec: AOD not found!\n");
511 // fix for temporary bug in ESDfilter
512 // the AODs with null vertex pointer didn't pass the PhysSel
513 if(!aod->GetPrimaryVertex() || TMath::Abs(aod->GetMagneticField())<0.001) return;
514 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
515 AliInputEventHandler *inputHandler=(AliInputEventHandler*)mgr->GetInputEventHandler();
516 AliPIDResponse *pidResp=inputHandler->GetPIDResponse();
517 fPidHF->SetPidResponse(pidResp);
520 fHistNEvents->Fill(0); // count event
521 // Post the data already here
524 fCounter->StoreEvent(aod,fAnalysisCuts,fReadMC);
526 Bool_t isEvSel=fAnalysisCuts->IsEventSelected(aod);
527 if(fAnalysisCuts->IsEventRejectedDueToTrigger())fHistNEvents->Fill(2);
528 if(fAnalysisCuts->IsEventRejectedDueToNotRecoVertex())fHistNEvents->Fill(3);
529 if(fAnalysisCuts->IsEventRejectedDueToVertexContributors())fHistNEvents->Fill(4);
530 if(fAnalysisCuts->IsEventRejectedDueToZVertexOutsideFiducialRegion())fHistNEvents->Fill(5);
531 // if(fAnalysisCuts->IsEventRejectedDueToPileup())fHistNEvents->Fill(6);
532 if(fAnalysisCuts->IsEventRejectedDueToCentrality()) fHistNEvents->Fill(7);
536 fHistNEvents->Fill(1);
538 TClonesArray *arrayMC=0;
539 AliAODMCHeader *mcHeader=0;
541 arrayMC = (TClonesArray*)aod->GetList()->FindObject(AliAODMCParticle::StdBranchName());
543 printf("AliAnalysisTaskCombinHF::UserExec: MC particles branch not found!\n");
548 mcHeader = (AliAODMCHeader*)aod->GetList()->FindObject(AliAODMCHeader::StdBranchName());
550 printf("AliAnalysisTaskCombinHF::UserExec: MC header branch not found!\n");
553 FillGenHistos(arrayMC);
556 Int_t ntracks=aod->GetNumberOfTracks();
557 fVtxZ = aod->GetPrimaryVertex()->GetZ();
558 fMultiplicity = AliVertexingHFUtils::GetNumberOfTrackletsInEtaRange(aod,-1.,1.);
560 // select and flag tracks
561 UChar_t* status = new UChar_t[ntracks];
562 for(Int_t iTr=0; iTr<ntracks; iTr++){
564 AliAODTrack* track=dynamic_cast<AliAODTrack*>(aod->GetTrack(iTr));
565 if(!track) AliFatal("Not a standard AOD");
566 if(IsTrackSelected(track)) status[iTr]+=1;
569 if (fPIDstrategy == knSigma) {
571 if(IsKaon(track)) status[iTr]+=2;
572 if(IsPion(track)) status[iTr]+=4;
574 else if (fPIDstrategy == kBayesianMaxProb || fPIDstrategy == kBayesianThres) {
576 Double_t *weights = new Double_t[AliPID::kSPECIES];
577 fPidHF->GetPidCombined()->ComputeProbabilities(track, fPidHF->GetPidResponse(), weights);
578 if (fPIDstrategy == kBayesianMaxProb) {
579 if (TMath::MaxElement(AliPID::kSPECIES, weights) == weights[AliPID::kKaon]) status[iTr] += 2;
580 if (TMath::MaxElement(AliPID::kSPECIES, weights) == weights[AliPID::kPion]) status[iTr] += 4;
582 if (fPIDstrategy == kBayesianThres) {
583 if (weights[AliPID::kKaon] > fBayesThresKaon) status[iTr] += 2;
584 if (weights[AliPID::kPion] > fBayesThresPion) status[iTr] += 4;
589 fHistTrackStatus->Fill(status[iTr]);
592 // build the combinatorics
595 Double_t dummypos[3]={0.,0.,0.};
596 AliAODVertex* v2=new AliAODVertex(dummypos,999.,-1,2);
597 AliAODVertex* v3=new AliAODVertex(dummypos,999.,-1,3);
598 // dummy values of track impact parameter, needed to build an AliAODRecoDecay object
599 Double_t d02[2]={0.,0.};
600 Double_t d03[3]={0.,0.,0.};
601 AliAODRecoDecay* tmpRD2 = new AliAODRecoDecay(0x0,2,0,d02);
602 AliAODRecoDecay* tmpRD3 = new AliAODRecoDecay(0x0,3,1,d03);
603 UInt_t pdg0[2]={321,211};
604 UInt_t pdgp[3]={321,211,211};
605 // UInt_t pdgs[3]={321,321,211};
607 Double_t px[3],py[3],pz[3];
609 fKaonTracks->Delete();
610 fPionTracks->Delete();
612 for(Int_t iTr1=0; iTr1<ntracks; iTr1++){
613 AliAODTrack* trK=dynamic_cast<AliAODTrack*>(aod->GetTrack(iTr1));
614 if(!trK) AliFatal("Not a standard AOD");
615 if((status[iTr1] & 1)==0) continue;
616 if(fDoEventMixing>0){
617 if(status[iTr1] & 2) fKaonTracks->AddLast(new TLorentzVector(trK->Px(),trK->Py(),trK->Pz(),trK->Charge()));
618 if(status[iTr1] & 4) fPionTracks->AddLast(new TLorentzVector(trK->Px(),trK->Py(),trK->Pz(),trK->Charge()));
620 if((status[iTr1] & 2)==0) continue;
621 Int_t chargeK=trK->Charge();
622 trK->GetPxPyPz(tmpp);
626 dgLabels[0]=trK->GetLabel();
627 for(Int_t iTr2=0; iTr2<ntracks; iTr2++){
628 if((status[iTr2] & 1)==0) continue;
629 if((status[iTr2] & 4)==0) continue;
630 if(iTr1==iTr2) continue;
631 AliAODTrack* trPi1=dynamic_cast<AliAODTrack*>(aod->GetTrack(iTr2));
632 if(!trPi1) AliFatal("Not a standard AOD");
633 Int_t chargePi1=trPi1->Charge();
634 trPi1->GetPxPyPz(tmpp);
638 dgLabels[1]=trPi1->GetLabel();
639 if(chargePi1==chargeK){
640 if(fMeson==kDzero) FillLSHistos(421,2,tmpRD2,px,py,pz,pdg0,chargePi1);
645 v2->AddDaughter(trK);
646 v2->AddDaughter(trPi1);
647 tmpRD2->SetSecondaryVtx(v2);
648 Bool_t ok=FillHistos(421,2,tmpRD2,px,py,pz,pdg0,arrayMC,dgLabels);
649 v2->RemoveDaughters();
652 for(Int_t iTr3=iTr2+1; iTr3<ntracks; iTr3++){
653 if((status[iTr3] & 1)==0) continue;
654 if((status[iTr3] & 4)==0) continue;
655 if(iTr1==iTr3) continue;
656 AliAODTrack* trPi2=dynamic_cast<AliAODTrack*>(aod->GetTrack(iTr3));
657 if(!trPi2) AliFatal("Not a standard AOD");
658 Int_t chargePi2=trPi2->Charge();
659 if(chargePi2==chargeK) continue;
661 trPi2->GetPxPyPz(tmpp);
665 dgLabels[2]=trPi2->GetLabel();
666 v3->AddDaughter(trK);
667 v3->AddDaughter(trPi1);
668 v3->AddDaughter(trPi2);
669 tmpRD3->SetSecondaryVtx(v3);
670 Bool_t ok=FillHistos(411,3,tmpRD3,px,py,pz,pdgp,arrayMC,dgLabels);
671 v3->RemoveDaughters();
684 fNSelected->Fill(nSelected);
686 fCounter->StoreCandidates(aod,nFiltered,kTRUE);
687 fCounter->StoreCandidates(aod,nSelected,kFALSE);
688 fEventInfo->SetString(Form("Ev%d_esd%d_Pi%d_K%d",mgr->GetNcalls(),((AliAODHeader*)aod->GetHeader())->GetEventNumberESDFile(),fPionTracks->GetEntries(),fKaonTracks->GetEntries()));
689 if(fDoEventMixing==1){
690 Int_t ind=GetPoolIndex(fVtxZ,fMultiplicity);
692 fEventsPerPool->Fill(fVtxZ,fMultiplicity);
693 fEventBuffer[ind]->Fill();
694 if(fEventBuffer[ind]->GetEntries() >= fNumberOfEventsForMixing){
695 fMixingsPerPool->Fill(fVtxZ,fMultiplicity);
696 DoMixingWithPools(ind);
700 }else if(fDoEventMixing==2){ // mix with cuts, no pools
701 fEventBuffer[0]->Fill();
704 PostData(2,fCounter);
709 //________________________________________________________________________
710 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){
711 // Fill histos for LS candidates
713 tmpRD->SetPxPyPzProngs(nProngs,px,py,pz);
714 Double_t pt = tmpRD->Pt();
715 Double_t minv2 = tmpRD->InvMass2(nProngs,pdgdau);
716 if(minv2>fMinMass*fMinMass && minv2<fMaxMass*fMaxMass){
717 Double_t rapid = tmpRD->Y(pdgD);
718 if(fAnalysisCuts->IsInFiducialAcceptance(pt,rapid)){
719 if(charge>0) fMassVsPtVsYLSpp->Fill(TMath::Sqrt(minv2),pt,rapid);
720 else fMassVsPtVsYLSmm->Fill(TMath::Sqrt(minv2),pt,rapid);
726 //________________________________________________________________________
727 void AliAnalysisTaskCombinHF::FillGenHistos(TClonesArray* arrayMC){
728 // Fill histos with generated quantities
729 Int_t totPart=arrayMC->GetEntriesFast();
736 for(Int_t ip=0; ip<totPart; ip++){
737 AliAODMCParticle *part = (AliAODMCParticle*)arrayMC->At(ip);
738 if(TMath::Abs(part->GetPdgCode())==thePDG){
739 Int_t orig=AliVertexingHFUtils::CheckOrigin(arrayMC,part,fGoUpToQuark);
740 fHistCheckOrigin->Fill(orig);
741 if(fPromptFeeddown==kFeeddown && orig!=5) continue;
742 else if(fPromptFeeddown==kPrompt && orig!=4) continue;
743 else if(fPromptFeeddown==kBoth && orig<4) continue;
744 fHistCheckOriginSel->Fill(orig);
746 Bool_t isGoodDecay=kFALSE;
747 Int_t labDau[4]={-1,-1,-1,-1};
749 deca=AliVertexingHFUtils::CheckD0Decay(arrayMC,part,labDau);
750 if(part->GetNDaughters()!=2) continue;
751 if(deca==1) isGoodDecay=kTRUE;
752 }else if(fMeson==kDplus){
753 deca=AliVertexingHFUtils::CheckDplusDecay(arrayMC,part,labDau);
754 if(deca>0) isGoodDecay=kTRUE;
756 fHistCheckDecChan->Fill(deca);
758 // printf(Form("Meson %d Label of daughters not filled correctly -- %d\n",fMeson,isGoodDecay));
759 continue; //protection against unfilled array of labels
761 Bool_t isInAcc=CheckAcceptance(arrayMC,nProng,labDau);
762 if(isInAcc) fHistCheckDecChanAcc->Fill(deca);
764 Double_t ptgen=part->Pt();
765 Double_t ygen=part->Y();
766 if(fAnalysisCuts->IsInFiducialAcceptance(ptgen,ygen)){
767 fPtVsYGen->Fill(ptgen,ygen);
768 if(TMath::Abs(ygen)<0.5) fPtVsYGenLimAcc->Fill(ptgen,ygen);
769 if(isInAcc) fPtVsYGenAcc->Fill(ptgen,ygen);
771 if(TMath::Abs(ygen)<0.9) fPtVsYGenLargeAcc->Fill(ptgen,ygen);
777 //________________________________________________________________________
778 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){
779 // Fill histos for candidates with proper charge sign
781 Bool_t accept=kFALSE;
783 tmpRD->SetPxPyPzProngs(nProngs,px,py,pz);
784 Double_t pt = tmpRD->Pt();
785 Double_t minv2 = tmpRD->InvMass2(nProngs,pdgdau);
786 Double_t mass=TMath::Sqrt(minv2);
788 if(minv2>fMinMass*fMinMass && minv2<fMaxMass*fMaxMass){
789 Double_t rapid = tmpRD->Y(pdgD);
790 if(fAnalysisCuts->IsInFiducialAcceptance(pt,rapid)){
791 fMassVsPtVsY->Fill(mass,pt,rapid);
794 Int_t signPdg[3]={0,0,0};
795 for(Int_t iii=0; iii<nProngs; iii++) signPdg[iii]=pdgdau[iii];
796 Int_t labD = tmpRD->MatchToMC(pdgD,arrayMC,nProngs,signPdg);
798 AliAODMCParticle* part = dynamic_cast<AliAODMCParticle*>(arrayMC->At(TMath::Abs(dgLabels[0])));
800 Int_t orig=AliVertexingHFUtils::CheckOrigin(arrayMC,part,fGoUpToQuark);
801 if((fPromptFeeddown==kFeeddown && orig==5)|| (fPromptFeeddown==kPrompt && orig==4) || (fPromptFeeddown==kBoth && orig>=4)) {
803 Int_t pdgCode = TMath::Abs( part->GetPdgCode() );
805 fMassVsPtVsYSig->Fill(mass,pt,rapid);
806 AliAODMCParticle* dmes = dynamic_cast<AliAODMCParticle*>(arrayMC->At(labD));
807 fPtVsYReco->Fill(dmes->Pt(),dmes->Y());
809 fMassVsPtVsYRefl->Fill(mass,pt,rapid);
814 fMassVsPtVsYBkg->Fill(mass,pt,rapid);
821 Double_t massRot=0;// calculated later only if candidate is acceptable
822 Double_t angleProngXY;
823 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])));
825 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])));
830 Double_t rotStep=(fMaxAngleForRot-fMinAngleForRot)/(fNRotations-1); // -1 is to ensure that the last rotation is done with angle=fMaxAngleForRot
831 Double_t rotStep3=(fMaxAngleForRot3-fMinAngleForRot3)/(fNRotations-1); // -1 is to ensure that the last rotation is done with angle=fMaxAngleForRot
833 for(Int_t irot=0; irot<fNRotations; irot++){
834 Double_t phirot=fMinAngleForRot+rotStep*irot;
837 Double_t tmpx2=px[2];
838 Double_t tmpy2=py[2];
839 px[0]=tmpx*TMath::Cos(phirot)-tmpy*TMath::Sin(phirot);
840 py[0]=tmpx*TMath::Sin(phirot)+tmpy*TMath::Cos(phirot);
841 if(pdgD==411 || pdgD==431){
842 Double_t phirot2=fMinAngleForRot3+rotStep3*irot;
843 px[2]=tmpx*TMath::Cos(phirot2)-tmpy*TMath::Sin(phirot2);
844 py[2]=tmpx*TMath::Sin(phirot2)+tmpy*TMath::Cos(phirot2);
846 tmpRD->SetPxPyPzProngs(nProngs,px,py,pz);
848 minv2 = tmpRD->InvMass2(nProngs,pdgdau);
849 if(minv2>fMinMass*fMinMass && minv2<fMaxMass*fMaxMass){
850 Double_t rapid = tmpRD->Y(pdgD);
851 if(fAnalysisCuts->IsInFiducialAcceptance(pt,rapid)){
852 massRot=TMath::Sqrt(minv2);
853 fMassVsPtVsYRot->Fill(massRot,pt,rapid);
855 fDeltaMass->Fill(massRot-mass);
857 Double_t pointRot[5]={mass,massRot-mass,ptOrig,pt-ptOrig,angleProngXY};
858 fDeltaMassFullAnalysis->Fill(pointRot);
864 if(pdgD==411 || pdgD==431){
869 fNormRotated->Fill(nRotated);
874 //________________________________________________________________________
875 void AliAnalysisTaskCombinHF::FillMEHistos(Int_t pdgD,Int_t nProngs, AliAODRecoDecay* tmpRD, Double_t* px, Double_t* py, Double_t* pz, UInt_t *pdgdau){
876 // Fill histos for candidates in MixedEvents
878 tmpRD->SetPxPyPzProngs(nProngs,px,py,pz);
879 Double_t pt = tmpRD->Pt();
880 Double_t minv2 = tmpRD->InvMass2(nProngs,pdgdau);
881 Double_t mass=TMath::Sqrt(minv2);
883 if(minv2>fMinMass*fMinMass && minv2<fMaxMass*fMaxMass){
884 Double_t rapid = tmpRD->Y(pdgD);
885 if(fAnalysisCuts->IsInFiducialAcceptance(pt,rapid)){
886 fMassVsPtVsYME->Fill(mass,pt,rapid);
891 //________________________________________________________________________
892 void AliAnalysisTaskCombinHF::FillMEHistosLS(Int_t pdgD,Int_t nProngs, AliAODRecoDecay* tmpRD, Double_t* px, Double_t* py, Double_t* pz, UInt_t *pdgdau, Int_t charge){
893 // Fill histos for candidates in MixedEvents
895 tmpRD->SetPxPyPzProngs(nProngs,px,py,pz);
896 Double_t pt = tmpRD->Pt();
897 Double_t minv2 = tmpRD->InvMass2(nProngs,pdgdau);
898 Double_t mass=TMath::Sqrt(minv2);
900 if(minv2>fMinMass*fMinMass && minv2<fMaxMass*fMaxMass){
901 Double_t rapid = tmpRD->Y(pdgD);
902 if(fAnalysisCuts->IsInFiducialAcceptance(pt,rapid)){
903 if(charge>0) fMassVsPtVsYMELSpp->Fill(mass,pt,rapid);
904 if(charge<0) fMassVsPtVsYMELSmm->Fill(mass,pt,rapid);
909 //________________________________________________________________________
910 Bool_t AliAnalysisTaskCombinHF::IsTrackSelected(AliAODTrack* track){
911 // track selection cuts
913 if(track->Charge()==0) return kFALSE;
914 if(track->GetID()<0&&!fKeepNegID)return kFALSE;
915 if(!(track->TestFilterMask(fFilterMask))) return kFALSE;
916 if(!SelectAODTrack(track,fTrackCutsAll)) return kFALSE;
920 //________________________________________________________________________
921 Bool_t AliAnalysisTaskCombinHF::IsKaon(AliAODTrack* track){
922 // kaon selection cuts
924 if(!fPidHF) return kTRUE;
925 Int_t isKaon=fPidHF->MakeRawPid(track,AliPID::kKaon);
926 Double_t mom=track->P();
927 if(SelectAODTrack(track,fTrackCutsKaon)) {
928 if(isKaon>=1) return kTRUE;
929 if(isKaon<=-1) return kFALSE;
930 switch(fPIDselCaseZero){// isKaon=0
933 return kTRUE;// always accept
938 if(isKaon>=0 && track->P()>fmaxPforIDKaon)return kTRUE;// accept only if in a compatibility band starting from p=fmaxPforIDKaon
943 if(track->P()>fmaxPforIDKaon)return kTRUE;
944 AliPIDResponse *pidResp=fPidHF->GetPidResponse();// more elaborated strategy: asymmetric cuts, with fix momenta and nsigma ranges for the moment
945 Double_t nsigma=pidResp->NumberOfSigmasTPC(track,AliPID::kKaon);
946 if(nsigma>-2.&& nsigma<3. && mom<0.6)isKaon=1;
947 else if(nsigma>-1.&& nsigma<3.&& mom<0.8)isKaon=1;
948 if(isKaon==1)return kTRUE;
953 AliWarning(Form("WRONG CASE OF PID STRATEGY SELECTED: %d (can range from 0 to 2)",fPIDselCaseZero));
954 return kFALSE;// actually case 0 could be set as the default and return kTRUE
961 //_______________________________________________________________________
962 Bool_t AliAnalysisTaskCombinHF::IsPion(AliAODTrack* track){
963 // pion selection cuts
965 if(!fPidHF) return kTRUE;
966 Int_t isPion=fPidHF->MakeRawPid(track,AliPID::kPion);
967 Double_t mom=track->P();
968 if(SelectAODTrack(track,fTrackCutsPion)) {
969 if(isPion>=1) return kTRUE;
970 if(isPion<=-1) return kFALSE;
971 switch(fPIDselCaseZero){// isPion=0
974 return kTRUE;// always accept
979 if(track->P()>fmaxPforIDPion)return kTRUE;// accept only if in a compatibility band starting from p=fmaxPforIDPion
984 // more elaborated strategy: asymmetric cuts, with fix momenta and nsigma ranges for the moment
985 if(track->P()>fmaxPforIDPion)return kTRUE;
986 AliPIDResponse *pidResp=fPidHF->GetPidResponse();
987 Double_t nsigma=pidResp->NumberOfSigmasTPC(track,AliPID::kPion);
988 if(nsigma<2.&& nsigma>-3. && mom<0.6)isPion=1;
989 else if(nsigma<1. && nsigma> -3. && mom<0.8)isPion=1;
990 if(isPion==1)return kTRUE;
995 AliWarning(Form("WRONG CASE OF PID STRATEGY SELECTED: %d (can range from 0 to 2)",fPIDselCaseZero));
996 return kFALSE;// actually case 0 could be set as the default and return kTRUE
1004 //________________________________________________________________________
1005 Bool_t AliAnalysisTaskCombinHF::SelectAODTrack(AliAODTrack *track, AliESDtrackCuts *cuts){
1006 // AOD track selection
1008 if(!cuts) return kTRUE;
1010 AliESDtrack esdTrack(track);
1011 // set the TPC cluster info
1012 esdTrack.SetTPCClusterMap(track->GetTPCClusterMap());
1013 esdTrack.SetTPCSharedMap(track->GetTPCSharedMap());
1014 esdTrack.SetTPCPointsF(track->GetTPCNclsF());
1015 if(!cuts->IsSelected(&esdTrack)) return kFALSE;
1020 //_________________________________________________________________
1021 Bool_t AliAnalysisTaskCombinHF::CheckAcceptance(TClonesArray* arrayMC,Int_t nProng, Int_t *labDau){
1022 // check if the decay products are in the good eta and pt range
1023 for (Int_t iProng = 0; iProng<nProng; iProng++){
1024 AliAODMCParticle* mcPartDaughter=dynamic_cast<AliAODMCParticle*>(arrayMC->At(labDau[iProng]));
1025 if(!mcPartDaughter) return kFALSE;
1026 Double_t eta = mcPartDaughter->Eta();
1027 Double_t pt = mcPartDaughter->Pt();
1028 if (TMath::Abs(eta) > fEtaAccCut || pt < fPtAccCut) return kFALSE;
1032 //_________________________________________________________________
1033 Int_t AliAnalysisTaskCombinHF::GetPoolIndex(Double_t zvert, Double_t mult){
1034 // check in which of the pools the current event falls
1035 if(!fzVertPoolLims || !fMultPoolLims) return 0;
1036 Int_t theBinZ=TMath::BinarySearch(fNzVertPoolsLimSize,fzVertPoolLims,zvert);
1037 if(theBinZ<0 || theBinZ>=fNzVertPoolsLimSize) return -1;
1038 Int_t theBinM=TMath::BinarySearch(fNMultPoolsLimSize,fMultPoolLims,mult);
1039 if(theBinM<0 || theBinM>=fNMultPoolsLimSize) return -1;
1040 return fNMultPools*theBinZ+theBinM;
1042 //_________________________________________________________________
1043 void AliAnalysisTaskCombinHF::ResetPool(Int_t poolIndex){
1044 // delete the contets of the pool
1045 if(poolIndex<0 || poolIndex>fNzVertPools*fNMultPools) return;
1046 delete fEventBuffer[poolIndex];
1047 fEventBuffer[poolIndex]=new TTree(Form("EventBuffer_%d",poolIndex), "Temporary buffer for event mixing");
1048 fEventBuffer[poolIndex]->Branch("zVertex", &fVtxZ);
1049 fEventBuffer[poolIndex]->Branch("multiplicity", &fMultiplicity);
1050 fEventBuffer[poolIndex]->Branch("eventInfo", "TObjString",&fEventInfo);
1051 fEventBuffer[poolIndex]->Branch("karray", "TObjArray", &fKaonTracks);
1052 fEventBuffer[poolIndex]->Branch("parray", "TObjArray", &fPionTracks);
1055 //_________________________________________________________________
1056 Bool_t AliAnalysisTaskCombinHF::CanBeMixed(Double_t zv1, Double_t zv2, Double_t mult1, Double_t mult2){
1058 if(TMath::Abs(zv2-zv1)>fMaxzVertDistForMix) return kFALSE;
1059 if(TMath::Abs(mult2-mult1)>fMaxMultDiffForMix) return kFALSE;
1062 //_________________________________________________________________
1063 void AliAnalysisTaskCombinHF::DoMixingWithCuts(){
1064 // perform mixed event analysis
1066 if(fDoEventMixing==0) return;
1067 Int_t nEvents=fEventBuffer[0]->GetEntries();
1068 if(fDebug > 1) printf("AnalysisTaskCombinHF::DoMixingWithCuts Start Event Mixing of %d events\n",nEvents);
1070 TObjArray* karray=0x0;
1071 TObjArray* parray=0x0;
1072 Double_t zVertex,mult;
1073 TObjString* eventInfo=0x0;
1074 fEventBuffer[0]->SetBranchAddress("karray", &karray);
1075 fEventBuffer[0]->SetBranchAddress("parray", &parray);
1076 fEventBuffer[0]->SetBranchAddress("eventInfo",&eventInfo);
1077 fEventBuffer[0]->SetBranchAddress("zVertex", &zVertex);
1078 fEventBuffer[0]->SetBranchAddress("multiplicity", &mult);
1079 Double_t d02[2]={0.,0.};
1080 Double_t d03[3]={0.,0.,0.};
1081 AliAODRecoDecay* tmpRD2 = new AliAODRecoDecay(0x0,2,0,d02);
1082 AliAODRecoDecay* tmpRD3 = new AliAODRecoDecay(0x0,3,1,d03);
1083 UInt_t pdg0[2]={321,211};
1084 // UInt_t pdgp[3]={321,211,211};
1085 Double_t px[3],py[3],pz[3];
1086 Int_t evId1,esdId1,nk1,np1;
1087 Int_t evId2,esdId2,nk2,np2;
1089 for(Int_t iEv1=0; iEv1<nEvents; iEv1++){
1090 fEventBuffer[0]->GetEvent(iEv1);
1091 TObjArray* karray1=(TObjArray*)karray->Clone();
1092 Double_t zVertex1=zVertex;
1093 Double_t mult1=mult;
1094 Int_t nKaons=karray1->GetEntries();
1095 Int_t nPionsForCheck=parray->GetEntries();
1096 sscanf((eventInfo->String()).Data(),"Ev%d_esd%d_Pi%d_K%d",&evId1,&esdId1,&np1,&nk1);
1097 if(nk1!=nKaons || np1!=nPionsForCheck){
1098 printf("AnalysisTaskCombinHF::DoMixingWithCuts ERROR: read event does not match to the stored one\n");
1102 for(Int_t iEv2=0; iEv2<fNumberOfEventsForMixing; iEv2++){
1103 Int_t iToMix=iEv1+iEv2+1;
1104 if(iEv1>=(nEvents-fNumberOfEventsForMixing)) iToMix=iEv1-iEv2-1;
1105 if(iToMix<0) continue;
1106 if(iToMix==iEv1) continue;
1107 if(iToMix<iEv1) continue;
1108 fEventBuffer[0]->GetEvent(iToMix);
1109 Double_t zVertex2=zVertex;
1110 Double_t mult2=mult;
1111 if(TMath::Abs(zVertex2-zVertex1)<0.0001 && TMath::Abs(mult2-mult1)<0.001){
1112 printf("AnalysisTaskCombinHF::DoMixingWithCuts ERROR: same event in mixing??? %d %d %f %f %f %f\n",iEv1,iEv2,zVertex1,zVertex2,mult1,mult2);
1115 TObjArray* parray2=(TObjArray*)parray->Clone();
1116 Int_t nPions=parray2->GetEntries();
1117 Int_t nKaonsForCheck=karray->GetEntries();
1118 sscanf((eventInfo->String()).Data(),"Ev%d_esd%d_Pi%d_K%d",&evId2,&esdId2,&np2,&nk2);
1119 if(nk2!=nKaonsForCheck || np2!=nPions){
1120 printf("AnalysisTaskCombinHF::DoMixingWithCuts ERROR: read event does not match to the stored one\n");
1124 if(evId2==evId1 && esdId2==esdId1){
1125 printf("AnalysisTaskCombinHF::DoMixingWithCuts ERROR: same event in mixing??? %d %d nK=%d %d nPi=%d %d\n",evId1,evId2,nKaons,nKaonsForCheck,nPionsForCheck,nPions);
1129 if(CanBeMixed(zVertex1,zVertex2,mult1,mult2)){
1130 for(Int_t iTr1=0; iTr1<nKaons; iTr1++){
1131 TLorentzVector* trK=(TLorentzVector*)karray1->At(iTr1);
1132 Double_t chargeK=trK->T();
1136 for(Int_t iTr2=0; iTr2<nPions; iTr2++){
1137 TLorentzVector* trPi1=(TLorentzVector*)parray2->At(iTr2);
1138 Double_t chargePi1=trPi1->T();
1139 px[1] = trPi1->Px();
1140 py[1] = trPi1->Py();
1141 pz[1] = trPi1->Pz();
1142 if(fMeson==kDzero && chargePi1*chargeK<0){
1143 FillMEHistos(421,2,tmpRD2,px,py,pz,pdg0);
1145 if(fMeson==kDzero && chargePi1*chargeK>0){
1146 FillMEHistosLS(421,2,tmpRD2,px,py,pz,pdg0,(Int_t)chargePi1);
1158 //_________________________________________________________________
1159 void AliAnalysisTaskCombinHF::DoMixingWithPools(Int_t poolIndex){
1160 // perform mixed event analysis
1162 if(fDoEventMixing==0) return;
1163 if(poolIndex<0 || poolIndex>fNzVertPools*fNMultPools) return;
1165 Int_t nEvents=fEventBuffer[poolIndex]->GetEntries();
1166 if(fDebug > 1) printf("AliAnalysisTaskCombinHF::DoMixingWithPools Start Event Mixing of %d events\n",nEvents);
1167 TObjArray* karray=0x0;
1168 TObjArray* parray=0x0;
1169 Double_t zVertex,mult;
1170 TObjString* eventInfo=0x0;
1171 fEventBuffer[poolIndex]->SetBranchAddress("karray", &karray);
1172 fEventBuffer[poolIndex]->SetBranchAddress("parray", &parray);
1173 fEventBuffer[poolIndex]->SetBranchAddress("eventInfo",&eventInfo);
1174 fEventBuffer[poolIndex]->SetBranchAddress("zVertex", &zVertex);
1175 fEventBuffer[poolIndex]->SetBranchAddress("multiplicity", &mult);
1177 // dummy values of track impact parameter, needed to build an AliAODRecoDecay object
1178 Double_t d02[2]={0.,0.};
1179 Double_t d03[3]={0.,0.,0.};
1180 AliAODRecoDecay* tmpRD2 = new AliAODRecoDecay(0x0,2,0,d02);
1181 AliAODRecoDecay* tmpRD3 = new AliAODRecoDecay(0x0,3,1,d03);
1182 UInt_t pdg0[2]={321,211};
1183 UInt_t pdgp[3]={321,211,211};
1184 Double_t px[3],py[3],pz[3];
1185 Int_t evId1,esdId1,nk1,np1;
1186 Int_t evId2,esdId2,nk2,np2;
1188 for(Int_t iEv1=0; iEv1<nEvents; iEv1++){
1189 fEventBuffer[poolIndex]->GetEvent(iEv1);
1190 TObjArray* karray1=(TObjArray*)karray->Clone();
1191 Double_t zVertex1=zVertex;
1192 Double_t mult1=mult;
1193 Int_t nKaons=karray1->GetEntries();
1194 Int_t nPionsForCheck=parray->GetEntries();
1195 sscanf((eventInfo->String()).Data(),"Ev%d_esd%d_Pi%d_K%d",&evId1,&esdId1,&np1,&nk1);
1196 if(nk1!=nKaons || np1!=nPionsForCheck){
1197 printf("AliAnalysisTaskCombinHF::DoMixingWithPools ERROR: read event does not match to the stored one\n");
1201 for(Int_t iEv2=0; iEv2<nEvents; iEv2++){
1202 if(iEv2==iEv1) continue;
1203 fEventBuffer[poolIndex]->GetEvent(iEv2);
1204 Double_t zVertex2=zVertex;
1205 Double_t mult2=mult;
1206 if(TMath::Abs(zVertex2-zVertex1)<0.0001 && TMath::Abs(mult2-mult1)<0.001){
1207 printf("AliAnalysisTaskCombinHF::DoMixingWithPools ERROR: same event in mixing??? %d %d %f %f %f %f\n",iEv1,iEv2,zVertex1,zVertex2,mult1,mult2);
1210 TObjArray* parray2=(TObjArray*)parray->Clone();
1211 Int_t nPions=parray2->GetEntries();
1212 Int_t nKaonsForCheck=karray->GetEntries();
1213 sscanf((eventInfo->String()).Data(),"Ev%d_esd%d_Pi%d_K%d",&evId2,&esdId2,&np2,&nk2);
1214 if(nk2!=nKaonsForCheck || np2!=nPions){
1215 printf("AliAnalysisTaskCombinHF::DoMixingWithPools ERROR: read event does not match to the stored one\n");
1219 if(evId2==evId1 && esdId2==esdId1){
1220 printf("AliAnalysisTaskCombinHF::DoMixingWithPools ERROR: same event in mixing??? %d %d nK=%d %d nPi=%d %d\n",evId1,evId2,nKaons,nKaonsForCheck,nPionsForCheck,nPions);
1224 TObjArray* parray3=0x0;
1228 if(iEv3==iEv1) iEv3=iEv2+2;
1229 if(iEv3>=nEvents) iEv3=iEv2-3;
1230 if(nEvents==2) iEv3=iEv1;
1231 if(iEv3<0) iEv3=iEv2-1;
1232 fEventBuffer[poolIndex]->GetEvent(iEv3);
1233 parray3=(TObjArray*)parray->Clone();
1234 nPions3=parray3->GetEntries();
1236 for(Int_t iTr1=0; iTr1<nKaons; iTr1++){
1237 TLorentzVector* trK=(TLorentzVector*)karray1->At(iTr1);
1238 Double_t chargeK=trK->T();
1242 for(Int_t iTr2=0; iTr2<nPions; iTr2++){
1243 TLorentzVector* trPi1=(TLorentzVector*)parray2->At(iTr2);
1244 Double_t chargePi1=trPi1->T();
1245 px[1] = trPi1->Px();
1246 py[1] = trPi1->Py();
1247 pz[1] = trPi1->Pz();
1248 if(chargePi1*chargeK<0){
1250 FillMEHistos(421,2,tmpRD2,px,py,pz,pdg0);
1253 for(Int_t iTr3=iTr2+1; iTr3<nPions3; iTr3++){
1254 TLorentzVector* trPi2=(TLorentzVector*)parray3->At(iTr3);
1255 Double_t chargePi2=trPi2->T();
1256 px[2] = trPi2->Px();
1257 py[2] = trPi2->Py();
1258 pz[2] = trPi2->Pz();
1259 if(chargePi2*chargeK<0){
1260 FillMEHistos(411,3,tmpRD3,px,py,pz,pdgp);
1265 }else if(chargePi1*chargeK>0){
1266 if(fMeson==kDzero) FillMEHistosLS(421,2,tmpRD2,px,py,pz,pdg0,(Int_t)chargePi1);
1278 //_________________________________________________________________
1279 void AliAnalysisTaskCombinHF::FinishTaskOutput()
1281 // perform mixed event analysis
1282 if(fDoEventMixing==0) return;
1283 printf("AliAnalysisTaskCombinHF: FinishTaskOutput\n");
1285 if(fDoEventMixing==1){
1286 for(Int_t i=0; i<fNOfPools; i++){
1287 Int_t nEvents=fEventBuffer[i]->GetEntries();
1288 if(nEvents>1) DoMixingWithPools(i);
1290 }else if(fDoEventMixing==2){
1294 //_________________________________________________________________
1295 void AliAnalysisTaskCombinHF::Terminate(Option_t */*option*/)
1297 // Terminate analysis
1299 if(fDebug > 1) printf("AliAnalysisTaskCombinHF: Terminate() \n");
1300 fOutput = dynamic_cast<TList*> (GetOutputData(1));
1302 printf("ERROR: fOutput not available\n");
1305 fHistNEvents = dynamic_cast<TH1F*>(fOutput->FindObject("hNEvents"));
1307 printf("Number of analyzed events = %d\n",(Int_t)fHistNEvents->GetBinContent(2));
1309 printf("ERROR: fHistNEvents not available\n");