1 // Dihadron correlations task - simple task to read ESD or AOD input,
2 // calculate same- and mixed-event correlations, and fill THnSparse
3 // output. -A. Adare, Apr 2011
13 #include <TProfile2D.h>
16 #include "AliAnalysisUtils.h"
17 #include "AliAODEvent.h"
18 #include "AliAODInputHandler.h"
19 #include "AliAnalysisManager.h"
20 #include "AliAnalysisTask.h"
21 #include "AliCentrality.h"
22 #include "AliDhcTask.h"
23 #include "AliESDEvent.h"
24 #include "AliESDInputHandler.h"
25 #include "AliESDMuonTrack.h"
26 #include "AliESDtrackCuts.h"
28 #include "AliVParticle.h"
35 //________________________________________________________________________
36 AliDhcTask::AliDhcTask()
37 : AliAnalysisTaskSE(), fVerbosity(0), fEtaMax(1), fZVtxMax(10), fPtMin(0.25), fPtMax(15),
38 fTrackDepth(1000), fPoolSize(200), fTracksName(), fDoWeights(kFALSE), fFillMuons(kFALSE),
39 fPtTACrit(kTRUE), fAllTAHists(kFALSE), fMixInEtaT(kFALSE),
40 fEtaTLo(-1.0), fEtaTHi(1.0), fEtaALo(-1.0), fEtaAHi(1.0), fOmitFirstEv(kTRUE),
41 fDoFillSame(kFALSE), fDoMassCut(kFALSE), fCheckVertex(kTRUE), fClassName(),
42 fCentMethod("V0M"), fNBdeta(20), fNBdphi(36), fTriggerMatch(kTRUE),
43 fBPtT(0x0), fBPtA(0x0), fBCent(0x0), fBZvtx(0x0),
44 fMixBCent(0x0), fMixBZvtx(0x0), fHEffT(0x0), fHEffA(0x0),
45 fESD(0x0), fAOD(0x0), fOutputList(0x0), fHEvt(0x0), fHTrk(0x0), fHPoolReady(0x0),
46 fHPtAss(0x0), fHPtTrg(0x0), fHPtTrgEvt(0x0),
47 fHPtTrgNorm1S(0x0), fHPtTrgNorm1M(0x0), fHPtTrgNorm2S(0x0), fHPtTrgNorm2M(0x0),
48 fHCent(0x0), fHZvtx(0x0), fNbins(0), fHSs(0x0), fHMs(0x0), fHPts(0x0), fHSMass(0x0), fHMMass(0x0),
49 fHQATp(0x0), fHQAAp(0x0), fHQATpCorr(0x0), fHQAApCorr(0x0),
50 fHQATm(0x0), fHQAAm(0x0), fHQATmCorr(0x0), fHQAAmCorr(0x0),
51 fHPtCentT(0x0), fHPtCentA(0x0), fIndex(0x0),
52 fCentrality(99), fZVertex(99), fEsdTPCOnly(0), fPoolMgr(0),
58 //________________________________________________________________________
59 AliDhcTask::AliDhcTask(const char *name, Bool_t def)
60 : AliAnalysisTaskSE(name), fVerbosity(0), fEtaMax(1), fZVtxMax(10), fPtMin(0.25), fPtMax(15),
61 fTrackDepth(1000), fPoolSize(200), fTracksName(), fDoWeights(kFALSE), fFillMuons(kFALSE),
62 fPtTACrit(kTRUE), fAllTAHists(kFALSE), fMixInEtaT(kFALSE),
63 fEtaTLo(-1.0), fEtaTHi(1.0), fEtaALo(-1.0), fEtaAHi(1.0), fOmitFirstEv(kTRUE),
64 fDoFillSame(kFALSE), fDoMassCut(kFALSE), fCheckVertex(kTRUE), fClassName(),
65 fCentMethod("V0M"), fNBdeta(20), fNBdphi(36), fTriggerMatch(kTRUE),
66 fBPtT(0x0), fBPtA(0x0), fBCent(0x0), fBZvtx(0x0),
67 fMixBCent(0x0), fMixBZvtx(0x0), fHEffT(0x0), fHEffA(0x0),
68 fESD(0x0), fAOD(0x0), fOutputList(0x0), fHEvt(0x0), fHTrk(0x0), fHPoolReady(0x0),
69 fHPtAss(0x0), fHPtTrg(0x0), fHPtTrgEvt(0x0),
70 fHPtTrgNorm1S(0x0), fHPtTrgNorm1M(0x0), fHPtTrgNorm2S(0x0), fHPtTrgNorm2M(0x0),
71 fHCent(0x0), fHZvtx(0x0), fNbins(0), fHSs(0x0), fHMs(0x0), fHPts(0x0), fHSMass(0x0), fHMMass(0x0),
72 fHQATp(0x0), fHQAAp(0x0), fHQATpCorr(0x0), fHQAApCorr(0x0),
73 fHQATm(0x0), fHQAAm(0x0), fHQATmCorr(0x0), fHQAAmCorr(0x0),
74 fHPtCentT(0x0), fHPtCentA(0x0), fIndex(0x0),
75 fCentrality(99), fZVertex(99), fEsdTPCOnly(0), fPoolMgr(0),
80 // Define input and output slots here
81 // Input slot #0 works with a TChain
82 DefineInput(0, TChain::Class());
83 // Output slot #0 id reserved by the base class for AOD
84 // Output slot #1 writes into a TH1 container
85 DefineOutput(1, TList::Class());
87 fBranchNames="ESD:AliESDRun.,AliESDHeader.,PrimaryVertex.,SPDVertex.,TPCVertex.,Tracks "
88 "AOD:header,tracks,vertices,";
91 Double_t ptt[4] = {0.25, 1.0, 2.0, 15.0};
92 fBPtT = new TAxis(3,ptt);
93 Double_t pta[4] = {0.25, 1.0, 2.0, 15.0};
94 fBPtA = new TAxis(3,pta);
95 Double_t cent[2] = {-100.0, 100.0};
96 fBCent = new TAxis(1,cent);
97 Double_t zvtx[2] = {-10, 10};
98 fBZvtx = new TAxis(1,zvtx);
99 Double_t centmix[2] = {-100.0, 100.0};
100 fMixBCent = new TAxis(1,centmix);
101 Double_t zvtxmix[9] = {-10,-6,-4,-2,0,2,4,6,10};
102 fMixBZvtx = new TAxis(8,zvtxmix);
106 //________________________________________________________________________
107 void AliDhcTask::UserCreateOutputObjects()
110 // Called once (per slave on PROOF!)
113 fOutputList = new TList();
114 fOutputList->SetOwner(1);
116 fUtils = new AliAnalysisUtils();
120 PostData(1, fOutputList);
123 //________________________________________________________________________
124 void AliDhcTask::PrintDhcSettings()
126 AliInfo(Form("Dhc Task %s settings",fName.Data()));
127 AliInfo(Form(" centrality estimator %s", fCentMethod.Data()));
128 AliInfo(Form(" using tracks named %s", fTracksName.Data()));
129 AliInfo(Form(" efficiency correct triggers? %d", fHEffT!=0));
131 AliInfo(Form(" %d dimensions (t)", fHEffT->GetNdimensions()));
133 AliInfo(Form(" efficiency correct associates? %d", fHEffA!=0));
135 AliInfo(Form(" %d dimensions (a)", fHEffA->GetNdimensions()));
137 AliInfo(Form(" fill muons? %d", fFillMuons));
138 AliInfo(Form(" use pTT > pTA criterion? %d", fPtTACrit));
139 AliInfo(Form(" create all pTT, pTA hists? %d", fAllTAHists));
140 AliInfo(Form(" Mix in eta_T bins instead of z_vertex? %d", fMixInEtaT));
141 AliInfo(Form(" trigger eta range %f .. %f", fEtaTLo, fEtaTHi));
142 AliInfo(Form(" associate eta range %f .. %f", fEtaALo, fEtaAHi));
143 AliInfo(Form(" fill same event in any case? %d", fDoFillSame));
144 AliInfo(Form(" do invariant mass cut? %d", fDoMassCut));
145 AliInfo(Form(" omit first event? %d\n", fOmitFirstEv));
146 AliInfo(Form(" check the vertex? %d\n", fCheckVertex));
149 //________________________________________________________________________
150 void AliDhcTask::BookHistos()
154 if (fVerbosity > 1) {
155 AliInfo(Form("Number of pt(t) bins: %d", fBPtT->GetNbins()));
156 for (Int_t i=1; i<=fBPtT->GetNbins(); i++) {
157 AliInfo(Form("pt(t) bin %d, %f to %f", i, fBPtT->GetBinLowEdge(i), fBPtT->GetBinUpEdge(i)));
159 AliInfo(Form("Number of pt(a) bins: %d", fBPtA->GetNbins()));
160 for (Int_t i=1; i<=fBPtA->GetNbins(); i++) {
161 AliInfo(Form("pt(a) bin %d, %f to %f", i, fBPtA->GetBinLowEdge(i), fBPtA->GetBinUpEdge(i)));
165 Int_t nPtAssc=fBPtA->GetNbins();
166 Int_t nPtTrig=fBPtT->GetNbins();
167 Int_t nCent=fBCent->GetNbins();
168 Int_t nZvtx=fBZvtx->GetNbins();
169 Double_t ptt[nPtTrig+1];
170 ptt[0] = fBPtT->GetBinLowEdge(1);
171 for (Int_t i=1; i<=nPtTrig; i++) {
172 ptt[i] = fBPtT->GetBinUpEdge(i);
174 Double_t pta[nPtAssc+1];
175 pta[0] = fBPtA->GetBinLowEdge(1);
176 for (Int_t i=1; i<=nPtAssc; i++) {
177 pta[i] = fBPtA->GetBinUpEdge(i);
179 Double_t cent[nCent+1];
180 cent[0] = fBCent->GetBinLowEdge(1);
181 for (Int_t i=1; i<=nCent; i++) {
182 cent[i] = fBCent->GetBinUpEdge(i);
184 Double_t zvtx[nZvtx+1];
185 zvtx[0] = fBZvtx->GetBinLowEdge(1);
186 for (Int_t i=1; i<=nZvtx; i++) {
187 zvtx[i] = fBZvtx->GetBinUpEdge(i);
190 fHEvt = new TH2F("fHEvt", "Event-level variables; Zvtx; Cent", nZvtx, zvtx, nCent, cent);
191 fOutputList->Add(fHEvt);
192 fHTrk = new TH2F("fHTrk", "Track-level variables",
193 100, 0, TMath::TwoPi(), 100, -fEtaMax, +fEtaMax);
194 fOutputList->Add(fHTrk);
196 // Centrality mixing axis
197 Int_t nCentBins=fMixBCent->GetNbins();
198 Double_t centBins[nCentBins+1];
199 centBins[0] = fMixBCent->GetBinLowEdge(1);
200 for (Int_t i=1; i<=nCentBins; i++) {
201 centBins[i] = fMixBCent->GetBinUpEdge(i);
203 // Z-vertex mixing axis
204 Int_t nZvtxBins=fMixBZvtx->GetNbins();
205 Double_t zvtxbin[nZvtxBins+1];
206 zvtxbin[0] = fMixBZvtx->GetBinLowEdge(1);
207 for (Int_t i=1; i<=nZvtxBins; i++) {
208 zvtxbin[i] = fMixBZvtx->GetBinUpEdge(i);
210 fHPoolReady = new TH2F("fHPoolReady","mixing started", nZvtxBins, zvtxbin, nCentBins, centBins);
211 fOutputList->Add(fHPoolReady);
213 fHPtAss = new TH1F("fHPtAss","PtAssoc;P_{T} (GeV/c) [GeV/c]",nPtAssc,pta);
214 fOutputList->Add(fHPtAss);
215 fHPtTrg = new TH1F("fHPtTrg","PtTrig;P_{T} (GeV/c) [GeV/c]",nPtTrig,ptt);
216 fOutputList->Add(fHPtTrg);
217 fHPtTrgEvt = new TH1F("fHPtTrgEvt","PtTrig;P_{T} (GeV/c) [GeV/c]",nPtTrig,ptt);
218 fHPtTrgNorm1S = new TH3F("fHPtTrgNorm1S","PtTrig;P_{T} (GeV/c) [GeV/c];centrality;z_{vtx}",nPtTrig,ptt,nCent,cent,nZvtx,zvtx);
219 fOutputList->Add(fHPtTrgNorm1S);
220 fHPtTrgNorm1M = (TH3*) fHPtTrgNorm1S->Clone("fHPtTrgNorm1M");
221 fOutputList->Add(fHPtTrgNorm1M);
222 fHPtTrgNorm2S = (TH3*) fHPtTrgNorm1S->Clone("fHPtTrgNorm2S");
223 fOutputList->Add(fHPtTrgNorm2S);
224 fHPtTrgNorm2M = (TH3*) fHPtTrgNorm1S->Clone("fHPtTrgNorm2M");
225 fOutputList->Add(fHPtTrgNorm2M);
227 fHCent = new TH1F("fHCent","Cent;bins",nCent,cent);
228 fOutputList->Add(fHCent);
229 fHZvtx = new TH1F("fHZvtx","Zvertex;bins",nZvtx,zvtx);
230 fOutputList->Add(fHZvtx);
232 fHQATp = new TH3F("fHQATp","QA trigger;p_{T} (GeV/c);#eta;#phi",
235 36,0.0,TMath::TwoPi());
236 fOutputList->Add(fHQATp);
237 fHQAAp = new TH3F("fHQAAp","QA associated;p_{T} (GeV/c);#eta;#phi",
240 36,0.0,TMath::TwoPi());
241 fOutputList->Add(fHQAAp);
242 fHQATpCorr = (TH3 *) fHQATp->Clone("fHQATpCorr");
243 fOutputList->Add(fHQATpCorr);
244 fHQAApCorr = (TH3 *) fHQAAp->Clone("fHQAApCorr");
245 fOutputList->Add(fHQAApCorr);
246 fHQATm = (TH3 *) fHQATp->Clone("fHQATm");
247 fOutputList->Add(fHQATm);
248 fHQAAm = (TH3 *) fHQAAp->Clone("fHQAAm");
249 fOutputList->Add(fHQAAm);
250 fHQATmCorr = (TH3 *) fHQATm->Clone("fHQATmCorr");
251 fOutputList->Add(fHQATmCorr);
252 fHQAAmCorr = (TH3 *) fHQAAm->Clone("fHQAAmCorr");
253 fOutputList->Add(fHQAAmCorr);
255 fHPtCentT = new TH2F("fHPtCentT",Form("trigger particles;p_{T} (GeV/c);centrality (%s)",fCentMethod.Data()),
257 100,cent[0],cent[nCent]);
258 fOutputList->Add(fHPtCentT);
259 fHPtCentA = new TH2F("fHPtCentA",Form("associated particles;p_{T} (GeV/c);centrality (%s)",fCentMethod.Data()),
261 100,cent[0],cent[nCent]);
262 fOutputList->Add(fHPtCentA);
264 fNbins = nPtTrig*nPtAssc*nCent*nZvtx;
265 fHSs = new TH2*[fNbins];
266 fHMs = new TH2*[fNbins];
267 fHPts = new TH1*[fNbins];
268 fHSMass = new TH1*[fNbins];
269 fHMMass = new TH1*[fNbins];
271 fIndex = new TFormula("GlobIndex","(t-1)*[0]*[1]*[2]+(z-1)*[0]*[1]+(x-1)*[0]+(y-1)+0*[4]");
272 fIndex->SetParameters(nPtTrig,nPtAssc,nZvtx,nCent);
273 fIndex->SetParNames("NTrigBins","NAssocBins", "NZvertexBins", "NCentBins");
274 fOutputList->Add(fIndex);
277 for (Int_t c=1; c<=nCent; ++c) {
278 for (Int_t z=1; z<=nZvtx; ++z) {
279 for (Int_t t=1; t<=nPtTrig; ++t) {
280 for (Int_t a=1; a<=nPtAssc; ++a) {
286 if ((a>t)&&!fAllTAHists) {
290 if (z==1 && t==1 && a==1) {
291 TString title(Form("cen=%d (%.1f to %.1f)",
292 c, fBCent->GetBinLowEdge(c), fBCent->GetBinUpEdge(c)));
293 fHSMass[count] = new TH1F(Form("hSMass%d",count), Form("Mass Same Event %s;m (GeV)",title.Data()), 10000, 0,10);
294 fOutputList->Add(fHSMass[count]);
295 fHMMass[count] = new TH1F(Form("hMMass%d",count), Form("Mass Mixed Event %s;m (GeV)",title.Data()), 10000, 0,10);
296 fOutputList->Add(fHMMass[count]);
299 TString title(Form("cen=%d (%.1f to %.1f), zVtx=%d (%.1f to %.1f)",
300 c, fBCent->GetBinLowEdge(c), fBCent->GetBinUpEdge(c),
301 z, fBZvtx->GetBinLowEdge(z), fBZvtx->GetBinUpEdge(z)));
302 fHPts[count] = new TH1F(Form("hPt%d",count), Form("Ptdist %s;p_{T} (GeV/c)",title.Data()), 200,0,20);
303 fOutputList->Add(fHPts[count]);
305 TString title(Form("cen=%d (%.1f to %.1f), zVtx=%d (%.1f to %.1f), trig=%d (%.1f to %.1f), assoc=%d (%.1f to %.1f)",
306 c, fBCent->GetBinLowEdge(c), fBCent->GetBinUpEdge(c),
307 z, fBZvtx->GetBinLowEdge(z), fBZvtx->GetBinUpEdge(z),
308 t, fBPtT->GetBinLowEdge(t), fBPtT->GetBinUpEdge(t),
309 a, fBPtA->GetBinLowEdge(a), fBPtA->GetBinUpEdge(a)));
310 fHSs[count] = new TH2F(Form("hS%d",count), Form("Signal %s;#Delta #varphi;#Delta #eta",title.Data()),
311 fNBdphi,-0.5*TMath::Pi(),1.5*TMath::Pi(),fNBdeta,-2*fEtaMax,2*fEtaMax);
312 fHMs[count] = new TH2F(Form("hM%d",count), Form("Mixed %s;#Delta #varphi;#Delta #eta",title.Data()),
313 fNBdphi,-0.5*TMath::Pi(),1.5*TMath::Pi(),fNBdeta,-2*fEtaMax,2*fEtaMax);
314 fOutputList->Add(fHSs[count]);
315 fOutputList->Add(fHMs[count]);
316 Int_t tcount = (Int_t)fIndex->Eval(t,a,z,c);
318 cout << count << " " << tcount << ": " << title << endl;
320 AliFatal(Form("Index mismatch: %d %d", count, tcount));
328 //________________________________________________________________________
329 void AliDhcTask::SetAnaMode(Int_t iAna)
332 SetFillMuons(kFALSE);
337 } else if (iAna==kMuH) {
343 } else if (iAna==kHMu) {
349 } else if (iAna==kMuMu) {
355 } else if (iAna==kPSide) {
356 SetFillMuons(kFALSE);
361 } else if (iAna==kASide) {
362 SetFillMuons(kFALSE);
368 AliInfo(Form("Unrecognized analysis option: %d", iAna));
372 //________________________________________________________________________
373 void AliDhcTask::InitEventMixer()
375 // The effective pool size in events is set by trackDepth, so more
376 // low-mult events are required to maintain the threshold than
377 // high-mult events. Centrality pools are indep. of data histogram
378 // binning, no need to match.
381 Int_t nCentBins=fMixBCent->GetNbins();
382 Double_t centBins[nCentBins+1];
383 centBins[0] = fMixBCent->GetBinLowEdge(1);
384 for (Int_t i=1; i<=nCentBins; i++) {
385 centBins[i] = fMixBCent->GetBinUpEdge(i);
389 Int_t nZvtxBins=fMixBZvtx->GetNbins();
390 Double_t zvtxbin[nZvtxBins+1];
391 zvtxbin[0] = fMixBZvtx->GetBinLowEdge(1);
392 for (Int_t i=1; i<=nZvtxBins; i++) {
393 zvtxbin[i] = fMixBZvtx->GetBinUpEdge(i);
396 fPoolMgr = new AliEvtPoolManager();
397 fPoolMgr->SetTargetTrackDepth(fTrackDepth);
399 fPoolMgr->SetDebug(1);
400 fPoolMgr->InitEventPools(fPoolSize, nCentBins, centBins, nZvtxBins, zvtxbin);
403 //________________________________________________________________________
404 void AliDhcTask::UserExec(Option_t *)
406 // Main loop, called for each event.
411 if (fUtils->IsFirstEventInChunk(InputEvent()))
415 // Get event pointers, check for signs of life
416 Int_t dType = -1; // Will be set to kESD or kAOD.
417 fESD = dynamic_cast<AliESDEvent*>(InputEvent());
418 fAOD = dynamic_cast<AliAODEvent*>(InputEvent());
424 AliError("Neither fESD nor fAOD available");
428 // select specific trigger classes?
429 if (fClassName.Length()>0) {
430 TString strFiredClass;
432 strFiredClass = fESD->GetFiredTriggerClasses();
434 strFiredClass = fAOD->GetFiredTriggerClasses();
436 if (fVerbosity > 10) {
437 AliInfo(Form("Trigger class selection: This event has classes %s", strFiredClass.Data()));
438 AliInfo(Form("Trigger class selection: selecting classes %s", fClassName.Data()));
441 TObjArray *arrClass = fClassName.Tokenize(",");
442 Int_t nClass = arrClass->GetEntries();
445 Bool_t bAccEvent = kFALSE;
446 for (Int_t iClass=0; iClass<nClass; iClass++) {
447 strOneClass = arrClass->At(iClass)->GetName();
448 if (strFiredClass.Contains(strOneClass))
455 if (fVerbosity > 10) {
456 AliInfo(Form("After trigger class selection: This event has classes %s", strFiredClass.Data()));
461 if (fTracksName.Contains("Gen"))
464 // Centrality, vertex, other event variables...
467 TList *list = InputEvent()->GetList();
468 TClonesArray *tcaTracks = 0;
470 tcaTracks = dynamic_cast<TClonesArray*>(list->FindObject(fTracksName));
472 fCentrality = tcaTracks->GetEntries();
475 const AliESDVertex* vertex = fESD->GetPrimaryVertex();
476 fZVertex = vertex->GetZ();
477 if (fCheckVertex && !VertexOk()) {
479 AliInfo(Form("Event REJECTED (ESD vertex not OK). z = %.1f", fZVertex));
482 if(fESD->GetCentrality()) {
484 fESD->GetCentrality()->GetCentralityPercentile(fCentMethod);
486 } else if (dType == kAOD) {
487 const AliAODVertex* vertex = fAOD->GetPrimaryVertex();
488 fZVertex = vertex->GetZ();
489 if (fCheckVertex && !VertexOk()) {
491 Info("Exec()", "Event REJECTED (AOD vertex not OK). z = %.1f", fZVertex);
494 AliAODHeader * header = dynamic_cast<AliAODHeader*>(fAOD);
495 if(!header) AliFatal("Not a standard AOD");
497 const AliCentrality *aodCent = header->GetCentralityP();
499 fCentrality = aodCent->GetCentralityPercentile(fCentMethod);
504 // Fill event histogram
505 fHEvt->Fill(fZVertex, fCentrality);
506 if (fCentrality > fBCent->GetXmax() || fCentrality < fBCent->GetXmin()) {
508 AliInfo(Form("Event REJECTED (centrality out of range). fCentrality = %.1f", fCentrality));
512 // Get pool containing tracks from other events like this one
513 AliEvtPool* pool = fPoolMgr->GetEventPool(fCentrality, fZVertex);
515 AliWarning(Form("No pool found. Centrality %f, ZVertex %f",
516 fCentrality, fZVertex));
520 // Get array of selected tracks
521 MiniEvent* sTracks = new MiniEvent(0); // deleted by pool mgr.
523 GetESDTracks(sTracks);
524 } else if (dType == kAOD) {
525 GetAODTracks(sTracks);
528 if (sTracks->size()==0) {
529 AliWarning(Form("Track array empty"));
534 if (!pool->IsReady()) {
535 pool->UpdatePool(sTracks);
536 if (fDoFillSame) { // fill same event right away if requested
537 Correlate(*sTracks, *sTracks, kSameEvt);
539 PostData(1, fOutputList);
543 if (pool->IsFirstReady()) {
544 fHPoolReady->Fill(fZVertex,fCentrality);
545 // recover events missed before the pool is ready
546 Int_t nEvs = pool->GetCurrentNEvents();
548 for (Int_t i=0; i<nEvs; ++i) {
549 MiniEvent* evI = pool->GetEvent(i);
550 for (Int_t j=0; j<nEvs; ++j) {
551 MiniEvent* evJ = pool->GetEvent(j);
553 if (!fDoFillSame) { // do not fill the same events twice
554 Correlate(*evI, *evJ, kSameEvt);
557 Correlate(*evI, *evJ, kDiffEvt);
562 } else { /* standard case: same event, then mix*/
563 Correlate(*sTracks, *sTracks, kSameEvt);
564 Int_t nMix = pool->GetCurrentNEvents();
565 for (Int_t jMix=0; jMix<nMix; ++jMix) {
566 MiniEvent* bgTracks = pool->GetEvent(jMix);
567 Correlate(*sTracks, *bgTracks, kDiffEvt);
571 pool->UpdatePool(sTracks);
572 PostData(1, fOutputList);
575 //________________________________________________________________________
576 void AliDhcTask::GetESDTracks(MiniEvent* miniEvt)
578 // Loop twice: 1. Count sel. tracks. 2. Fill vector.
580 if (fTracksName.IsNull()) {
581 const AliESDVertex *vtxSPD = fESD->GetPrimaryVertexSPD();
585 Int_t nTrax = fESD->GetNumberOfTracks();
587 AliInfo(Form("%d tracks in event",nTrax));
591 TObjArray arr(nTrax);
595 fEsdTPCOnly = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
596 //fEsdTPCOnly->SetMinNClustersTPC(70);
597 fEsdTPCOnly->SetMinNCrossedRowsTPC(70);
598 fEsdTPCOnly->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
601 for (Int_t i = 0; i < nTrax; ++i) {
602 AliESDtrack* esdtrack = fESD->GetTrack(i);
604 AliError(Form("Couldn't get ESD track %d\n", i));
607 Bool_t trkOK = fEsdTPCOnly->AcceptTrack(esdtrack);
610 Double_t pt = esdtrack->Pt();
611 Bool_t ptOK = pt >= fPtMin && pt < fPtMax;
614 Double_t eta = esdtrack->Eta();
615 if (TMath::Abs(eta) > fEtaMax)
618 // create a tpc only track
619 AliESDtrack *newtrack = AliESDtrackCuts::GetTPCOnlyTrack(fESD,esdtrack->GetID());
622 if (newtrack->Pt()<=0) {
627 AliExternalTrackParam exParam;
628 Bool_t relate = newtrack->RelateToVertexTPC(vtxSPD,fESD->GetMagneticField(),kVeryBig,&exParam);
634 // set the constraint parameters to the track
635 newtrack->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
638 ptOK = pt >= fPtMin && pt < fPtMax;
643 eta = esdtrack->Eta();
644 if (TMath::Abs(eta) > fEtaMax) {
652 for(Int_t itrack = 0; itrack < nSelTrax; itrack++) {
653 AliVTrack *esdtrack = static_cast<AliESDtrack*>(arr.At(itrack));
655 AliError(Form("ERROR: Could not retrieve esdtrack %d",itrack));
658 Double_t pt = esdtrack->Pt();
659 Double_t eta = esdtrack->Eta();
660 Double_t phi = esdtrack->Phi();
661 Int_t sign = esdtrack->Charge() > 0 ? 1 : -1;
662 if (IsTrigger(eta,pt)||IsAssociated(eta,pt))
663 miniEvt->push_back(AliMiniTrack(pt, eta, phi, sign));
666 TList *list = InputEvent()->GetList();
667 TClonesArray *tcaTracks = dynamic_cast<TClonesArray*>(list->FindObject(fTracksName));
670 AliError("Ptr to tcaTracks zero");
674 const Int_t ntracks = tcaTracks->GetEntries();
675 Int_t nGoodTracks = 0;
677 for (Int_t itrack = 0; itrack < ntracks; itrack++) {
678 AliVTrack *vtrack = static_cast<AliVTrack*>(tcaTracks->At(itrack));
680 AliError(Form("ERROR: Could not retrieve vtrack %d",itrack));
683 Double_t pt = vtrack->Pt();
684 Double_t eta = vtrack->Eta();
685 if (IsTrigger(eta,pt)||IsAssociated(eta,pt))
689 miniEvt->reserve(nGoodTracks);
691 AliError("Ptr to miniEvt zero");
694 // fill good tracks into minievent
695 for (Int_t itrack = 0; itrack < ntracks; itrack++) {
696 AliVTrack *vtrack = static_cast<AliVTrack*>(tcaTracks->At(itrack));
698 AliError(Form("ERROR: Could not retrieve vtrack %d",itrack));
701 Double_t pt = vtrack->Pt();
702 Double_t eta = vtrack->Eta();
703 Double_t phi = vtrack->Phi();
704 Int_t sign = vtrack->Charge() > 0 ? 1 : -1;
705 if (IsTrigger(eta,pt)||IsAssociated(eta,pt))
706 miniEvt->push_back(AliMiniTrack(pt, eta, phi, sign));
712 Int_t nGoodMuons = 0;
713 for (Int_t iMu = 0; iMu<fESD->GetNumberOfMuonTracks(); iMu++) {
714 AliESDMuonTrack* muonTrack = fESD->GetMuonTrack(iMu);
716 if (!IsGoodMUONtrack(*muonTrack))
718 Double_t ptMu = muonTrack->Pt();
719 Double_t etaMu = muonTrack->Eta();
720 if ((IsTrigger(etaMu,ptMu)||IsAssociated(etaMu,ptMu)) && (IsGoodMUONtrack(*muonTrack)))
724 miniEvt->reserve(miniEvt->size()+nGoodMuons);
725 // fill them into the mini event
726 for (Int_t iMu = 0; iMu<fESD->GetNumberOfMuonTracks(); iMu++) {
727 AliESDMuonTrack* muonTrack = fESD->GetMuonTrack(iMu);
729 if (!IsGoodMUONtrack(*muonTrack))
731 Double_t ptMu = muonTrack->Pt();
732 Double_t etaMu = muonTrack->Eta();
733 Double_t phiMu = muonTrack->Phi();
734 Int_t signMu = muonTrack->Charge() > 0 ? 1 : -1;
735 if (IsTrigger(etaMu,ptMu)||IsAssociated(etaMu,ptMu))
736 miniEvt->push_back(AliMiniTrack(ptMu, etaMu, phiMu, signMu));
742 //________________________________________________________________________
743 void AliDhcTask::GetAODTracks(MiniEvent* miniEvt)
745 // Loop twice: 1. Count sel. tracks. 2. Fill vector.
747 if (fTracksName.IsNull()) {
748 Int_t nTrax = fAOD->GetNumberOfTracks();
752 AliInfo(Form("%d tracks in event",nTrax));
755 for (Int_t i = 0; i < nTrax; ++i) {
756 AliAODTrack* aodtrack = dynamic_cast<AliAODTrack*>(fAOD->GetTrack(i));
757 if(!aodtrack) AliFatal("Not a standard AOD");
759 AliError(Form("Couldn't get AOD track %d\n", i));
762 // See $ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C
763 UInt_t tpcOnly = 1 << 7;
764 Bool_t trkOK = aodtrack->TestFilterBit(tpcOnly);
767 Double_t pt = aodtrack->Pt();
768 Double_t eta = aodtrack->Eta();
769 if (IsTrigger(eta,pt)||IsAssociated(eta,pt))
774 miniEvt->reserve(nSelTrax);
776 AliError("!miniEvt");
781 for (Int_t i = 0; i < nTrax; ++i) {
782 AliAODTrack* aodtrack = dynamic_cast<AliAODTrack*>(fAOD->GetTrack(i));
783 if(!aodtrack) AliFatal("Not a standard AOD");
785 AliError(Form("Couldn't get AOD track %d\n", i));
789 // See $ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C
790 UInt_t tpcOnly = 1 << 7;
791 Bool_t trkOK = aodtrack->TestFilterBit(tpcOnly);
794 Double_t pt = aodtrack->Pt();
795 Double_t eta = aodtrack->Eta();
796 Double_t phi = aodtrack->Phi();
797 Int_t sign = aodtrack->Charge() > 0 ? 1 : -1;
798 if (IsTrigger(eta,pt)||IsAssociated(eta,pt))
799 miniEvt->push_back(AliMiniTrack(pt, eta, phi, sign));
802 TList *list = InputEvent()->GetList();
803 TClonesArray *tcaTracks = dynamic_cast<TClonesArray*>(list->FindObject(fTracksName));
806 AliError("Ptr to tcaTracks zero");
810 const Int_t ntracks = tcaTracks->GetEntries();
811 Int_t nGoodTracks = 0;
813 for (Int_t itrack = 0; itrack < ntracks; itrack++) {
814 AliVTrack *vtrack = static_cast<AliVTrack*>(tcaTracks->At(itrack));
816 AliError(Form("ERROR: Could not retrieve vtrack %d",itrack));
819 Double_t pt = vtrack->Pt();
820 Double_t eta = vtrack->Eta();
821 if (IsTrigger(eta,pt)||IsAssociated(eta,pt))
825 miniEvt->reserve(nGoodTracks);
827 AliError("Ptr to miniEvt zero");
830 // fill good tracks into minievent
831 for (Int_t itrack = 0; itrack < ntracks; itrack++) {
832 AliVTrack *vtrack = static_cast<AliVTrack*>(tcaTracks->At(itrack));
834 AliError(Form("ERROR: Could not retrieve vtrack %d",itrack));
837 Double_t pt = vtrack->Pt();
838 Double_t eta = vtrack->Eta();
839 Double_t phi = vtrack->Phi();
840 Int_t sign = vtrack->Charge() > 0 ? 1 : -1;
841 if (IsTrigger(eta,pt)||IsAssociated(eta,pt))
842 miniEvt->push_back(AliMiniTrack(pt, eta, phi, sign));
848 Int_t nGoodMuons = 0;
849 for (Int_t iMu = 0; iMu<fAOD->GetNumberOfTracks(); iMu++) {
850 AliAODTrack* muonTrack = dynamic_cast<AliAODTrack*>(fAOD->GetTrack(iMu));
851 if(!muonTrack) AliFatal("Not a standard AOD");
853 if (!IsGoodMUONtrack(*muonTrack))
855 Double_t ptMu = muonTrack->Pt();
856 Double_t etaMu = muonTrack->Eta();
857 if ((IsTrigger(etaMu,ptMu)||IsAssociated(etaMu,ptMu)) && (IsGoodMUONtrack(*muonTrack)))
861 miniEvt->reserve(miniEvt->size()+nGoodMuons);
862 // fill them into the mini event
863 for (Int_t iMu = 0; iMu<fAOD->GetNumberOfTracks(); iMu++) {
864 AliAODTrack* muonTrack = dynamic_cast<AliAODTrack*>(fAOD->GetTrack(iMu));
865 if(!muonTrack) AliFatal("Not a standard AOD");
867 if (!IsGoodMUONtrack(*muonTrack))
869 Double_t ptMu = muonTrack->Pt();
870 Double_t etaMu = muonTrack->Eta();
871 Double_t phiMu = muonTrack->Phi();
872 Int_t signMu = muonTrack->Charge() > 0 ? 1 : -1;
873 if (IsTrigger(etaMu,ptMu)||IsAssociated(etaMu,ptMu))
874 miniEvt->push_back(AliMiniTrack(ptMu, etaMu, phiMu, signMu));
880 //________________________________________________________________________
881 Double_t AliDhcTask::DeltaPhi(Double_t phia, Double_t phib,
882 Double_t rangeMin, Double_t rangeMax) const
884 Double_t dphi = -999;
885 Double_t pi = TMath::Pi();
887 if (phia < 0) phia += 2*pi;
888 else if (phia > 2*pi) phia -= 2*pi;
889 if (phib < 0) phib += 2*pi;
890 else if (phib > 2*pi) phib -= 2*pi;
892 if (dphi < rangeMin) dphi += 2*pi;
893 else if (dphi > rangeMax) dphi -= 2*pi;
898 //________________________________________________________________________
899 Int_t AliDhcTask::Correlate(const MiniEvent &evt1, const MiniEvent &evt2, Int_t pairing)
901 // Triggered angular correlations. If pairing is kSameEvt, particles
902 // within evt1 are correlated. If kDiffEvt, correlate triggers from
903 // evt1 with partners from evt2.
905 Int_t cbin = fHCent->FindBin(fCentrality);
906 if (fHCent->IsBinOverflow(cbin) ||
907 fHCent->IsBinUnderflow(cbin))
910 Int_t zbin = fHZvtx->FindBin(fZVertex);
911 if (fHZvtx->IsBinOverflow(zbin) ||
912 fHZvtx->IsBinUnderflow(zbin))
915 Int_t iMax = evt1.size();
916 Int_t jMax = evt2.size();
919 if (pairing == kSameEvt) {
921 fHCent->Fill(fCentrality);
922 fHZvtx->Fill(fZVertex);
925 Int_t nZvtx = fHZvtx->GetNbinsX();
926 Int_t nPtTrig = fHPtTrg->GetNbinsX();
927 Int_t nPtAssc = fHPtAss->GetNbinsX();
929 Int_t globIndex = (cbin-1)*nZvtx*nPtTrig*nPtAssc+(zbin-1)*nPtTrig*nPtAssc;
930 Int_t ptindex = (Int_t)fIndex->Eval(1,1,zbin,cbin);
931 Int_t mindex = (Int_t)fIndex->Eval(1,1,1,cbin);
935 for (Int_t i=0; i<iMax; ++i) {
936 const AliMiniTrack &a(evt1.at(i));
937 Float_t pta = a.Pt();
938 fHPtTrgEvt->Fill(pta);
939 if (pairing == kSameEvt) {
940 fHPts[ptindex]->Fill(pta);
944 Bool_t bCountTrg; // only count the trigger if an associated particle is found
946 for (Int_t i=0; i<iMax; ++i) {
948 const AliMiniTrack &a(evt1.at(i));
950 Float_t pta = a.Pt();
951 Float_t etaa = a.Eta();
952 Float_t phia = a.Phi();
953 Int_t sgna = a.Sign();
955 // brief intermezzo in the trigger particle loop: do associated particle QA here in order to avoid double counting
956 if (pairing == kSameEvt) {
957 if (IsAssociated(etaa,pta)) {
958 Double_t aQAWght = 1.0;
960 const Int_t nEffDimA = fHEffA->GetNdimensions();
961 Int_t effBinA[nEffDimA];
962 effBinA[0] = fHEffA->GetAxis(0)->FindBin(etaa);
963 effBinA[1] = fHEffA->GetAxis(1)->FindBin(pta);
964 effBinA[2] = fHEffA->GetAxis(2)->FindBin(fCentrality);
965 effBinA[3] = fHEffA->GetAxis(3)->FindBin(fZVertex);
967 effBinA[4] = fHEffA->GetAxis(4)->FindBin(phia);
969 effBinA[5] = fHEffA->GetAxis(5)->FindBin(sgna);
972 aQAWght = fHEffA->GetBinContent(effBinA);
974 // fill every associated particle once unweighted, once weighted
976 fHQAAp->Fill(pta,etaa,phia);
977 fHQAApCorr->Fill(pta,etaa,phia,aQAWght);
979 fHQAAm->Fill(pta,etaa,phia);
980 fHQAAmCorr->Fill(pta,etaa,phia,aQAWght);
982 fHPtCentA->Fill(pta,fCentrality);
987 if (!IsTrigger(etaa,pta))
990 Int_t abin = fHPtAss->FindBin(pta);
992 // efficiency weighting
993 Double_t effWtT = 1.0;
996 const Int_t nEffDimT = fHEffT->GetNdimensions();
997 Int_t effBinT[nEffDimT];
998 effBinT[0] = fHEffT->GetAxis(0)->FindBin(etaa);
999 effBinT[1] = fHEffT->GetAxis(1)->FindBin(pta);
1000 effBinT[2] = fHEffT->GetAxis(2)->FindBin(fCentrality);
1001 effBinT[3] = fHEffT->GetAxis(3)->FindBin(fZVertex);
1003 effBinT[4] = fHEffT->GetAxis(4)->FindBin(phia);
1005 effBinT[5] = fHEffT->GetAxis(5)->FindBin(sgna);
1008 effWtT = fHEffT->GetBinContent(effBinT);
1011 if (pairing == kSameEvt) {
1012 fHTrk->Fill(phia,etaa);
1014 fHQATp->Fill(pta,etaa,phia);
1015 fHQATpCorr->Fill(pta,etaa,phia,effWtT);
1017 fHQATm->Fill(pta,etaa,phia);
1018 fHQATmCorr->Fill(pta,etaa,phia,effWtT);
1020 fHPtCentT->Fill(pta,fCentrality);
1022 fHPtTrgNorm1S->Fill(pta,fCentrality,fZVertex,effWtT);
1024 fHPtTrgNorm1M->Fill(pta,fCentrality,fZVertex,effWtT);
1028 for (Int_t j=0; j<jMax; ++j) {
1029 // Associated particles
1030 if (pairing == kSameEvt && i==j)
1033 const AliMiniTrack &b(evt2.at(j));
1035 Float_t ptb = b.Pt();
1036 Float_t etab = b.Eta();
1037 Float_t phib = b.Phi();
1038 Int_t sgnb = b.Sign();
1039 if (fPtTACrit&&(pta < ptb)) {
1043 if (!IsAssociated(etab,ptb))
1046 Int_t bbin = fHPtAss->FindBin(ptb);
1048 Float_t dphi = DeltaPhi(phia, phib);
1049 Float_t deta = etaa - etab;
1050 // invariant mass under mu mu assumption
1051 Float_t muMass2 = 0.1056583715*0.1056583715;
1052 Float_t ea2 = muMass2 + pta*pta*TMath::CosH(etaa)*TMath::CosH(etaa);
1053 Float_t eb2 = muMass2 + ptb*ptb*TMath::CosH(etab)*TMath::CosH(etab);
1054 Float_t papb = pta*TMath::Cos(phia)*ptb*TMath::Cos(phib) +
1055 pta*TMath::Sin(phia)*ptb*TMath::Sin(phib) +
1056 pta*TMath::SinH(etaa)*ptb*TMath::SinH(etab);
1057 Float_t mass = TMath::Sqrt(2.0*(muMass2 + TMath::Sqrt(ea2*eb2) - papb));
1058 Int_t q2 = sgna + sgnb;
1059 if ((q2==0) && fDoMassCut) {
1060 if (mass>3.0 && mass<3.2)
1062 if (mass>9.2&&mass<9.8)
1066 Int_t index = globIndex+(abin-1)*nPtAssc+(bbin-1);
1067 Double_t weight = 1.0;
1068 // number of trigger weight event-by-event (CMS method)
1070 Double_t nTrgs = fHPtTrgEvt->GetBinContent(abin);
1072 AliError(Form("Trying to work with number of triggers weight = %f",nTrgs));
1078 // efficiency weighting
1085 // associated particle
1086 const Int_t nEffDimA = fHEffA->GetNdimensions();
1087 Int_t effBinA[nEffDimA];
1088 effBinA[0] = fHEffA->GetAxis(0)->FindBin(etab);
1089 effBinA[1] = fHEffA->GetAxis(1)->FindBin(ptb);
1090 effBinA[2] = fHEffA->GetAxis(2)->FindBin(fCentrality);
1091 effBinA[3] = fHEffA->GetAxis(3)->FindBin(fZVertex);
1093 effBinA[4] = fHEffA->GetAxis(4)->FindBin(phib);
1095 effBinA[5] = fHEffA->GetAxis(5)->FindBin(sgnb);
1098 weight *= fHEffA->GetBinContent(effBinA);
1101 if (hist[index]) { // check if this histogram exists, relevant in the fPtTACrit==kFALSE case
1102 hist[index]->Fill(dphi,deta,weight);
1104 if (pairing == kSameEvt) {
1105 fHPtAss->Fill(ptb); // fill every associated particle every time it is used
1107 fHSMass[mindex]->Fill(mass);
1110 fHMMass[mindex]->Fill(mass);
1115 if (pairing == kSameEvt) {
1116 fHPtTrgNorm2S->Fill(pta,fCentrality,fZVertex,effWtT);
1118 fHPtTrgNorm2M->Fill(pta,fCentrality,fZVertex,effWtT);
1126 //________________________________________________________________________
1127 void AliDhcTask::Terminate(Option_t *)
1129 // Draw result to the screen
1130 // Called once at the end of the query
1133 //________________________________________________________________________
1134 Bool_t AliDhcTask::VertexOk() const
1136 // Modified from AliAnalyseLeadingTrackUE::VertexSelection()
1138 Int_t nContributors = 0;
1139 Double_t zVertex = 999;
1142 Int_t runno = InputEvent()->GetRunNumber();
1143 if (runno>=176326 && runno<=197692) { // year 12 and 13
1144 if (!fUtils->IsVertexSelected2013pA(InputEvent()))
1149 const AliESDVertex* vtx = fESD->GetPrimaryVertex();
1152 nContributors = vtx->GetNContributors();
1153 zVertex = vtx->GetZ();
1154 name = vtx->GetName();
1156 if (fAOD->GetNumberOfVertices() < 1)
1158 const AliAODVertex* vtx = fAOD->GetPrimaryVertex();
1159 nContributors = vtx->GetNContributors();
1160 zVertex = vtx->GetZ();
1161 name = vtx->GetName();
1164 // Reject if TPC-only vertex
1165 if (name.CompareTo("TPCVertex")==0)
1168 // Check # contributors and range...
1169 if( nContributors < 1 || TMath::Abs(zVertex) > fZVtxMax ) {
1176 //________________________________________________________________________
1177 Bool_t AliDhcTask::IsGoodMUONtrack(AliESDMuonTrack &track)
1179 // Applying track cuts for MUON tracks
1181 if (!track.ContainTrackerData())
1183 Double_t thetaTrackAbsEnd = TMath::ATan(track.GetRAtAbsorberEnd()/505.) * TMath::RadToDeg();
1184 if ((thetaTrackAbsEnd < 2.) || (thetaTrackAbsEnd > 10.))
1186 Double_t eta = track.Eta();
1187 if ((eta < -4.) || (eta > -2.5))
1189 if (fTriggerMatch) {
1190 if (!track.ContainTriggerData())
1192 if (track.GetMatchTrigger() < 0.5)
1198 //________________________________________________________________________
1199 Bool_t AliDhcTask::IsGoodMUONtrack(AliAODTrack &track)
1201 // Applying track cuts for MUON tracks
1203 if (!track.IsMuonTrack())
1205 Double_t dThetaAbs = TMath::ATan(track.GetRAtAbsorberEnd()/505.)* TMath::RadToDeg();
1206 if ((dThetaAbs<2.) || (dThetaAbs>10.))
1208 Double_t dEta = track.Eta();
1209 if ((dEta<-4.) || (dEta>-2.5))
1211 if (fTriggerMatch) {
1212 if (track.GetMatchTrigger()<0.5)
1218 //________________________________________________________________________
1219 Bool_t AliDhcTask::IsTrigger(Double_t eta, Double_t pt)
1221 // is in trigger eta,pt range?
1222 Int_t bin = fHPtTrg->FindBin(pt);
1223 if (fHPtTrg->IsBinOverflow(bin) || fHPtTrg->IsBinUnderflow(bin))
1226 if (eta<fEtaTLo || eta>fEtaTHi)
1232 //________________________________________________________________________
1233 Bool_t AliDhcTask::IsAssociated(Double_t eta, Double_t pt)
1235 // is in associated eta,pt range?
1236 Int_t bin = fHPtAss->FindBin(pt);
1237 if (fHPtAss->IsBinOverflow(bin) || fHPtAss->IsBinUnderflow(bin))
1240 if (eta<fEtaALo || eta>fEtaAHi)
1246 //________________________________________________________________________
1247 AliDhcTask::~AliDhcTask()