]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG3/muon/AliAnalysisTaskSingleMu.cxx
AliMixInputHandlerInfo : BeginEvent function for each input handler after fChain...
[u/mrichter/AliRoot.git] / PWG3 / muon / AliAnalysisTaskSingleMu.cxx
CommitLineData
aad6618e 1/**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
27de2dfb 16/* $Id$ */
17
662e37fe 18//-----------------------------------------------------------------------------
19/// \class AliAnalysisTaskSingleMu
20/// Analysis task for single muons in the spectrometer.
9728bcfd 21/// The output is a list of histograms.
b201705a 22/// The macro class can run on AODs or ESDs.
23/// In the latter case a flag can be activated to produce a tree as output.
9728bcfd 24/// If Monte Carlo information is present, some basics checks are performed.
662e37fe 25///
26/// \author Diego Stocco
27//-----------------------------------------------------------------------------
28
aad6618e 29//----------------------------------------------------------------------------
30// Implementation of the single muon analysis class
662e37fe 31// An example of usage can be found in the macro RunSingleMuAnalysisFromAOD.C.
aad6618e 32//----------------------------------------------------------------------------
33
34#define AliAnalysisTaskSingleMu_cxx
35
36// ROOT includes
aad6618e 37#include "TROOT.h"
9728bcfd 38#include "TH1.h"
39#include "TH2.h"
40#include "TH3.h"
41#include "TAxis.h"
42#include "TList.h"
662e37fe 43#include "TCanvas.h"
9728bcfd 44#include "TMath.h"
b201705a 45#include "TTree.h"
46#include "TTimeStamp.h"
589e3f71 47#include "TMap.h"
48#include "TObjString.h"
55065f3f 49#include "TObjArray.h"
589e3f71 50#include "TIterator.h"
51#include "TParameter.h"
52#include "TMCProcess.h"
aad6618e 53
54// STEER includes
589e3f71 55#include "AliAODInputHandler.h"
aad6618e 56#include "AliAODEvent.h"
57#include "AliAODTrack.h"
58#include "AliAODVertex.h"
aad6618e 59
9728bcfd 60#include "AliMCParticle.h"
61#include "AliStack.h"
62
b201705a 63#include "AliESDInputHandler.h"
64#include "AliESDEvent.h"
65#include "AliESDMuonTrack.h"
9728bcfd 66
589e3f71 67#include "AliMultiplicity.h"
93d6def1 68#include "AliCentrality.h"
589e3f71 69
70// ANALYSIS includes
71#include "AliAnalysisManager.h"
9728bcfd 72#include "AliAnalysisTaskSE.h"
4ab8d5a6 73#include "AliAnalysisDataSlot.h"
74#include "AliAnalysisDataContainer.h"
589e3f71 75
76// CORRFW includes
77#include "AliCFManager.h"
78#include "AliCFContainer.h"
79#include "AliCFGridSparse.h"
80#include "AliCFTrackKineCuts.h"
81#include "AliCFParticleGenCuts.h"
82#include "AliCFEventRecCuts.h"
83
aad6618e 84#include "AliAnalysisTaskSingleMu.h"
85
662e37fe 86/// \cond CLASSIMP
87ClassImp(AliAnalysisTaskSingleMu) // Class implementation in ROOT context
88/// \endcond
aad6618e 89
9728bcfd 90
aad6618e 91//________________________________________________________________________
589e3f71 92AliAnalysisTaskSingleMu::AliAnalysisTaskSingleMu(const char *name, Int_t fillTreeScaleDown, Bool_t keepAll) :
9728bcfd 93 AliAnalysisTaskSE(name),
589e3f71 94 fFillTreeScaleDown(fillTreeScaleDown),
b201705a 95 fKeepAll(keepAll),
589e3f71 96 fkNvtxContribCut(1),
4ab8d5a6 97 fTriggerClasses(0x0),
589e3f71 98 fCFManager(0),
9728bcfd 99 fHistoList(0),
b201705a 100 fHistoListMC(0),
589e3f71 101 fHistoListQA(0),
b201705a 102 fTreeSingleMu(0),
b201705a 103 fVarFloat(0),
104 fVarInt(0),
105 fVarChar(0),
106 fVarUInt(0),
107 fVarFloatMC(0),
589e3f71 108 fVarIntMC(0),
93d6def1 109 fAuxObjects(new TMap()),
110 fDebugString("")
aad6618e 111{
112 //
113 /// Constructor.
114 //
589e3f71 115 if ( fFillTreeScaleDown <= 0 )
b201705a 116 fKeepAll = kFALSE;
117
589e3f71 118 DefineOutput(1, AliCFContainer::Class());
9728bcfd 119 DefineOutput(2, TList::Class());
589e3f71 120 DefineOutput(3, TList::Class());
121 DefineOutput(4, TList::Class());
122
123 if ( fFillTreeScaleDown > 0 )
124 DefineOutput(5, TTree::Class());
125
55065f3f 126 fAuxObjects->SetOwner();
b201705a 127
55065f3f 128 SetTriggerClasses();
aad6618e 129}
130
9728bcfd 131
132//________________________________________________________________________
133AliAnalysisTaskSingleMu::~AliAnalysisTaskSingleMu()
aad6618e 134{
135 //
9728bcfd 136 /// Destructor
aad6618e 137 //
589e3f71 138
4ab8d5a6 139 delete fTriggerClasses;
140 // For proof: do not delete output containers
141 if ( ! AliAnalysisManager::GetAnalysisManager()->IsProofMode() ) {
142 delete fCFManager->GetParticleContainer(); // The container is not deleted by framework
143 delete fCFManager;
144 delete fHistoList;
145 delete fHistoListMC;
146 delete fHistoListQA;
147 delete fTreeSingleMu;
148 }
b201705a 149 delete fVarFloat;
150 delete fVarInt;
151 delete [] fVarChar;
152 delete fVarUInt;
153 delete fVarFloatMC;
154 delete fVarIntMC;
55065f3f 155 delete fAuxObjects;
9728bcfd 156}
aad6618e 157
9728bcfd 158
159//___________________________________________________________________________
b201705a 160void AliAnalysisTaskSingleMu::NotifyRun()
9728bcfd 161{
162 //
163 /// Use the event handler information to correctly fill the analysis flags:
164 /// - check if Monte Carlo information is present
165 //
166
589e3f71 167 if ( fMCEvent ) {
9728bcfd 168 AliInfo("Monte Carlo information is present");
169 }
170 else {
171 AliInfo("No Monte Carlo information in run");
aad6618e 172 }
589e3f71 173}
174
175
176//___________________________________________________________________________
177void AliAnalysisTaskSingleMu::FinishTaskOutput()
178{
179 //
180 /// Perform histogram normalization after the last analyzed event
181 /// but before merging
182 //
183
589e3f71 184 // Set the correct run limits for the histograms
185 // vs run number to cope with the merging
4ab8d5a6 186 Int_t histoIndex = -1;
589e3f71 187 Int_t indexPerRun[2] = {kHistoNeventsPerRun, kHistoNmuonsPerRun};
188 for ( Int_t ihisto=0; ihisto<2; ihisto++) {
189 histoIndex = GetHistoIndex(indexPerRun[ihisto]);
190 TH2F* histo2D = (TH2F*)fHistoList->At(histoIndex);
191 Double_t minX = 1e10, maxX = -1e10;
192 for (Int_t ibin=1; ibin<=histo2D->GetXaxis()->GetNbins(); ibin++){
193 TString runNum = histo2D->GetXaxis()->GetBinLabel(ibin);
194 minX = TMath::Min(runNum.Atof()-0.5, minX);
195 maxX = TMath::Max(runNum.Atof()+0.5, maxX);
196 }
197 histo2D->GetXaxis()->SetLimits(minX, maxX);
198 AliInfo(Form("Histogram %s run limits (%f, %f)",histo2D->GetName(), minX, maxX));
199 }
aad6618e 200}
201
9728bcfd 202
aad6618e 203//___________________________________________________________________________
9728bcfd 204void AliAnalysisTaskSingleMu::UserCreateOutputObjects()
aad6618e 205{
206 //
207 /// Create output histograms
208 //
9728bcfd 209 AliInfo(Form(" CreateOutputObjects of task %s\n", GetName()));
aad6618e 210
9728bcfd 211 // initialize histogram lists
589e3f71 212 if ( ! fHistoList ) fHistoList = new TList();
213 if ( ! fHistoListMC ) fHistoListMC = new TList();
214 if ( ! fHistoListQA ) fHistoListQA = new TList();
b201705a 215
216 // Init variables
217 fVarFloat = new Float_t [kNvarFloat];
218 fVarInt = new Int_t [kNvarInt];
219 fVarChar = new Char_t *[kNvarChar];
220 fVarUInt = new UInt_t [kNvarUInt];
221 fVarFloatMC = new Float_t [kNvarFloatMC];
222 fVarIntMC = new Int_t [kNvarIntMC];
589e3f71 223
224 const Int_t charWidth[kNvarChar] = {255};
225 for(Int_t ivar=0; ivar<kNvarChar; ivar++){
226 fVarChar[ivar] = new Char_t [charWidth[ivar]];
227 }
228
9728bcfd 229 Int_t nPtBins = 60;
589e3f71 230 Double_t ptMin = 0., ptMax = 30.;
9728bcfd 231 TString ptName("Pt"), ptTitle("p_{t}"), ptUnits("GeV/c");
589e3f71 232
55065f3f 233 Int_t nRapidityBins = 25;
234 Double_t rapidityMin = -4.5, rapidityMax = -2.;
4ab8d5a6 235 //TString rapidityName("Rapidity"), rapidityTitle("y"), rapidityUnits("");
236 TString rapidityName("Eta"), rapidityTitle("#eta"), rapidityUnits("");
589e3f71 237
238 Int_t nPhiBins = 36;
239 Double_t phiMin = 0.; Double_t phiMax = 2*TMath::Pi();
240 TString phiName("Phi"), phiTitle("#phi"), phiUnits("rad");
9728bcfd 241
589e3f71 242 Int_t nDcaBins = 30;
243 Double_t dcaMin = 0., dcaMax = 300.;
9728bcfd 244 TString dcaName("DCA"), dcaTitle("DCA"), dcaUnits("cm");
662e37fe 245
589e3f71 246 Int_t nVzBins = 40;
247 Double_t vzMin = -20., vzMax = 20.;
9728bcfd 248 TString vzName("Vz"), vzTitle("Vz"), vzUnits("cm");
249
589e3f71 250 Int_t nThetaAbsEndBins = 4;
251 Double_t thetaAbsEndMin = -0.5, thetaAbsEndMax = 3.5;
252 TString thetaAbsEndName("ThetaAbsEnd"), thetaAbsEndTitle("#theta_{abs}"), thetaAbsEndUnits("a.u.");
253
254 Int_t nChargeBins = 2;
255 Double_t chargeMin = -2, chargeMax = 2.;
256 TString chargeName("Charge"), chargeTitle("charge"), chargeUnits("e");
257
258 Int_t nMatchTrigBins = 4;
259 Double_t matchTrigMin = -0.5, matchTrigMax = 3.5;
260 TString matchTrigName("MatchTrig"), matchTrigTitle("Trigger match"), matchTrigUnits("");
9728bcfd 261
55065f3f 262 Int_t nTrigClassBins = fTriggerClasses->GetEntries();
263 Double_t trigClassMin = 0.5, trigClassMax = (Double_t)nTrigClassBins + 0.5;
4ab8d5a6 264 TString trigClassName("TrigClass"), trigClassTitle("Fired trigger class"), trigClassUnits("");
589e3f71 265
266 Int_t nGoodVtxBins = 3;
267 Double_t goodVtxMin = -0.5, goodVtxMax = 2.5;
268 TString goodVtxName("GoodVtx"), goodVtxTitle("Vertex flags"), goodVtxUnits("");
269
270 Int_t nMotherTypeBins = kNtrackSources;
271 Double_t motherTypeMin = -0.5, motherTypeMax = (Double_t)kNtrackSources - 0.5;
272 TString motherType("MotherType"), motherTypeTitle("motherType"), motherTypeUnits("");
9728bcfd 273
93d6def1 274 Int_t nCentralityBins = 10;
275 Double_t centralityMin = 0., centralityMax = 100.;
276 TString centralityName("Centrality"), centralityTitle("centrality"), centralityUnits("%");
4ab8d5a6 277
9728bcfd 278 TString trigName[kNtrigCuts];
279 trigName[kNoMatchTrig] = "NoMatch";
280 trigName[kAllPtTrig] = "AllPt";
281 trigName[kLowPtTrig] = "LowPt";
282 trigName[kHighPtTrig] = "HighPt";
283
284 TString srcName[kNtrackSources];
285 srcName[kCharmMu] = "Charm";
286 srcName[kBeautyMu] = "Beauty";
287 srcName[kPrimaryMu] = "Decay";
288 srcName[kSecondaryMu] = "Secondary";
289 srcName[kRecoHadron] = "Hadrons";
93d6def1 290 srcName[kUnknownPart] = "Unidentified";
9728bcfd 291
292 TH1F* histo1D = 0x0;
293 TH2F* histo2D = 0x0;
294 TString histoName, histoTitle;
295 Int_t histoIndex = 0;
296
589e3f71 297 // Multi-dimensional histo
93d6def1 298 Int_t nbins[kNvars] = {nPtBins, nRapidityBins, nPhiBins, nDcaBins, nVzBins, nThetaAbsEndBins, nChargeBins, nMatchTrigBins, nTrigClassBins, nGoodVtxBins, nMotherTypeBins, nCentralityBins};
299 Double_t xmin[kNvars] = {ptMin, rapidityMin, phiMin, dcaMin, vzMin, thetaAbsEndMin, chargeMin, matchTrigMin, trigClassMin, goodVtxMin, motherTypeMin, centralityMin};
300 Double_t xmax[kNvars] = {ptMax, rapidityMax, phiMax, dcaMax, vzMax, thetaAbsEndMax, chargeMax, matchTrigMax, trigClassMax, goodVtxMax, motherTypeMax, centralityMax};
301 TString axisTitle[kNvars] = {ptTitle, rapidityTitle, phiTitle, dcaTitle, vzTitle, thetaAbsEndTitle, chargeTitle, matchTrigTitle, trigClassTitle, goodVtxTitle, motherTypeTitle, centralityTitle};
302 TString axisUnits[kNvars] = {ptUnits, rapidityUnits, phiUnits, dcaUnits, vzUnits, thetaAbsEndUnits, chargeUnits, matchTrigUnits, trigClassUnits, goodVtxUnits, motherTypeUnits, centralityUnits};
662e37fe 303
4ab8d5a6 304 //TString stepTitle[kNsteps] = {"reconstructed", "in acceptance", "generated", "in acceptance (MC)"};
305 TString stepTitle[kNsteps] = {"reconstructed", "generated"};
589e3f71 306
307 // Create CF container
4ab8d5a6 308
309 // The framework has problems if the name of the object
310 // and the one of container differ
311 // To be complaint, get the name from container and set it
312 TString containerName = GetOutputSlot(1)->GetContainer()->GetName();
313
314 AliCFContainer* container = new AliCFContainer(containerName.Data(),"container for tracks",kNsteps,kNvars,nbins);
589e3f71 315
316 for ( Int_t idim = 0; idim<kNvars; idim++){
317 histoTitle = Form("%s (%s)", axisTitle[idim].Data(), axisUnits[idim].Data());
318 histoTitle.ReplaceAll("()","");
319
320 container->SetVarTitle(idim, histoTitle.Data());
321 container->SetBinLimits(idim, xmin[idim], xmax[idim]);
9728bcfd 322 }
589e3f71 323
324 for (Int_t istep=0; istep<kNsteps; istep++){
325 container->SetStepTitle(istep, stepTitle[istep].Data());
326 AliCFGridSparse* gridSparse = container->GetGrid(istep);
327
328 SetAxisLabel(gridSparse->GetAxis(kHvarTrigClass));
329 TAxis* isGoodVtxAxis = gridSparse->GetAxis(kHvarIsGoodVtx);
330 isGoodVtxAxis->SetBinLabel(1,Form("No vertex (contrib<%i)",fkNvtxContribCut));
331 isGoodVtxAxis->SetBinLabel(2,"Good vertex");
332 isGoodVtxAxis->SetBinLabel(3,"Pileup");
333 TAxis* motherTypeAxis = gridSparse->GetAxis(kHvarMotherType);
334 for (Int_t ibin=0; ibin<kNtrackSources; ibin++){
335 motherTypeAxis->SetBinLabel(ibin+1,srcName[ibin]);
336 }
9728bcfd 337 }
589e3f71 338
339 // Create cuts
340
341 //Particle-Level cuts:
342 AliCFParticleGenCuts* mcGenCuts = new AliCFParticleGenCuts();
343 mcGenCuts->SetNameTitle("mcGenCuts","MC particle generation cuts");
344 mcGenCuts->SetRequirePdgCode(13,kTRUE);
345 mcGenCuts->SetQAOn(fHistoListQA);
346
4ab8d5a6 347 /*
589e3f71 348 // MC kinematic cuts
349 AliCFTrackKineCuts *mcAccCuts = new AliCFTrackKineCuts();
350 mcAccCuts->SetNameTitle("mcAccCuts","MC-level acceptance cuts");
351 mcAccCuts->SetEtaRange(-4.,-2.5);
589e3f71 352 mcAccCuts->SetQAOn(fHistoListQA);
353
589e3f71 354 // Rec-Level kinematic cuts
355 AliCFTrackKineCuts *recAccCuts = new AliCFTrackKineCuts();
356 recAccCuts->SetNameTitle("recAccCuts","Reco-level acceptance cuts");
357 recAccCuts->SetEtaRange(-4.,-2.5);
358 recAccCuts->SetQAOn(fHistoListQA);
4ab8d5a6 359 */
589e3f71 360
589e3f71 361 TObjArray* mcGenList = new TObjArray(0) ;
362 mcGenList->AddLast(mcGenCuts);
363
4ab8d5a6 364 /*
589e3f71 365 TObjArray* mcAccList = new TObjArray(0);
366 mcAccList->AddLast(mcAccCuts);
367
589e3f71 368 TObjArray* recAccList = new TObjArray(0);
369 recAccList->AddLast(recAccCuts);
4ab8d5a6 370 */
589e3f71 371
589e3f71 372 // Create CF manager
373 fCFManager = new AliCFManager() ;
374 fCFManager->SetParticleContainer(container);
375
376 // Add cuts
377 // Dummy event container
378 Int_t dummyBins[1] = {1};
379 AliCFContainer* evtContainer = new AliCFContainer("dummyContainer","dummy contaier for events",1,1,dummyBins);
380 fCFManager->SetEventContainer(evtContainer);
381 fCFManager->SetEventCutsList(0,0x0);
382
383 // Init empty cuts (avoid warnings in framework)
384 for (Int_t istep=0; istep<kNsteps; istep++) {
385 fCFManager->SetParticleCutsList(istep,0x0);
662e37fe 386 }
4ab8d5a6 387 //fCFManager->SetParticleCutsList(kStepAcceptance,recAccList);
589e3f71 388 fCFManager->SetParticleCutsList(kStepGeneratedMC,mcGenList);
4ab8d5a6 389 //fCFManager->SetParticleCutsList(kStepAcceptanceMC,mcAccList);
662e37fe 390
b201705a 391 // Summary histos
589e3f71 392 histoName = "histoNeventsPerTrig";
393 histoTitle = "Number of events per trigger class";
394 histo2D = new TH2F(histoName.Data(), histoTitle.Data(), nTrigClassBins, trigClassMin, trigClassMax, 5, 0.5, 5.5);
395 histo2D->GetXaxis()->SetTitle("Fired class");
396 SetAxisLabel(histo2D->GetXaxis());
397 histo2D->GetYaxis()->SetBinLabel(1, "All events");
398 histo2D->GetYaxis()->SetBinLabel(2, "Good vtx events");
399 histo2D->GetYaxis()->SetBinLabel(3, "Pileup events");
400 histo2D->GetYaxis()->SetBinLabel(4, "All vertices");
401 histo2D->GetYaxis()->SetBinLabel(5, "Pileup vertices");
402 histoIndex = GetHistoIndex(kHistoNeventsPerTrig);
403 fHistoList->AddAt(histo2D, histoIndex);
404
b201705a 405 histoName = "histoMuonMultiplicity";
406 histoTitle = "Muon track multiplicity";
589e3f71 407 histo2D = new TH2F(histoName.Data(), histoTitle.Data(), 15, -0.5, 15-0.5,
408 nTrigClassBins, trigClassMin, trigClassMax);
409 histo2D->GetXaxis()->SetTitle("# of muons");
410 SetAxisLabel(histo2D->GetYaxis());
411 histoIndex = GetHistoIndex(kHistoMuonMultiplicity);
412 fHistoList->AddAt(histo2D, histoIndex);
413
414 histoName = "histoEventVz";
415 histoTitle = "All events IP Vz distribution";
4ab8d5a6 416 histo2D = new TH2F(histoName.Data(), histoTitle.Data(), nTrigClassBins, trigClassMin, trigClassMax, nVzBins, vzMin, vzMax);
417 histo2D->GetXaxis()->SetTitle("Fired class");
418 SetAxisLabel(histo2D->GetXaxis());
589e3f71 419 histoTitle = Form("%s (%s)", vzTitle.Data(), vzUnits.Data());
4ab8d5a6 420 histo2D->GetYaxis()->SetTitle(histoTitle.Data());
589e3f71 421 histoIndex = GetHistoIndex(kHistoEventVz);
4ab8d5a6 422 fHistoList->AddAt(histo2D, histoIndex);
b201705a 423
589e3f71 424 Int_t hRunIndex[2] = {kHistoNeventsPerRun, kHistoNmuonsPerRun};
425 TString hRunName[2] = {"histoNeventsPerRun", "histoNmuonsPerRun"};
426 TString hRunTitle[2] = {"Number of events per run", "Number of muons per run"};
427 for ( Int_t ihisto=0; ihisto<2; ihisto++){
428 histoName = hRunName[ihisto];
429 histoTitle = hRunTitle[ihisto];
430 histo2D = new TH2F(histoName.Data(), histoTitle.Data(),
431 1, 0., 0.,
432 nTrigClassBins, trigClassMin, trigClassMax);
433 histo2D->GetXaxis()->SetTitle("Run number");
434 SetAxisLabel(histo2D->GetYaxis());
435 histo2D->Sumw2();
436 histoIndex = hRunIndex[ihisto];
437 fHistoList->AddAt(histo2D, histoIndex);
438 }
439
440 // MC histos summary
93d6def1 441 Int_t hCheckVzIndex[3] = {kHistoCheckVzMC, kHistoCheckVzHasVtxMC, kHistoCheckVzNoPileupMC};
442 TString hCheckVzName[3] = {"histoCheckVz", "histoCheckVzHasVtx", "histoCheckVzIsPileup"};
443 TString hCheckVzTitle[3] = {"", " w/ vertex contributors", "w/ pileup SPD"};
444
445 for ( Int_t ihisto=0; ihisto<3; ihisto++ ) {
446 histoName = hCheckVzName[ihisto];
447 histoTitle = Form("Check IP Vz distribution %s", hCheckVzTitle[ihisto].Data());
448
449 histo2D = new TH2F(histoName.Data(), histoTitle.Data(),
450 nVzBins, vzMin, vzMax,
451 nVzBins, vzMin, vzMax);
452 histoTitle = Form("%s (%s)", vzTitle.Data(), vzUnits.Data());
453 histo2D->GetXaxis()->SetTitle(histoTitle.Data());
454 histoTitle = Form("%s MC (%s)", vzTitle.Data(), vzUnits.Data());
455 histo2D->GetYaxis()->SetTitle(histoTitle.Data());
456 histoIndex = GetHistoIndex(hCheckVzIndex[ihisto]);
457 fHistoListMC->AddAt(histo2D, histoIndex);
458 }
589e3f71 459
9728bcfd 460 // MC histos
461 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
462 for (Int_t isrc = 0; isrc < kNtrackSources; isrc++) {
463 histoName = Form("%sResolution%sTrig%s", ptName.Data(), trigName[itrig].Data(), srcName[isrc].Data());
464 histoTitle = Form("%s resolution. Trigger: %s (%s)", ptTitle.Data(), trigName[itrig].Data(), srcName[isrc].Data());
465 histo1D = new TH1F(histoName.Data(), histoTitle.Data(), 100, -5., 5.);
466 histo1D->GetXaxis()->SetTitle(Form("%s^{reco} - %s^{MC} (%s)", ptTitle.Data(), ptTitle.Data(), ptUnits.Data()));
b201705a 467 histoIndex = GetHistoIndex(kHistoPtResolutionMC, itrig, isrc);
9728bcfd 468 fHistoListMC->AddAt(histo1D, histoIndex);
469 }
470 }
471
b201705a 472 // Trees
4ab8d5a6 473 if ( fFillTreeScaleDown > 0 ) {
b201705a 474 TString leavesFloat[kNvarFloat] = {"Px", "Py", "Pz", "Pt",
475 "PxAtDCA", "PyAtDCA", "PzAtDCA", "PtAtDCA",
476 "PxUncorrected", "PyUncorrected", "PzUncorrected", "PtUncorrected",
477 "XUncorrected", "YUncorrected", "ZUncorrected",
478 "XatDCA", "YatDCA", "DCA",
589e3f71 479 "Eta", "Rapidity", "Charge", "RAtAbsEnd",
93d6def1 480 "IPVx", "IPVy", "IPVz", "Centrality"};
589e3f71 481 TString leavesInt[kNvarInt] = {"MatchTrig", "IsMuon", "IsGhost", "LoCircuit", "PassPhysicsSelection", "NVtxContrib", "NspdTracklets", "IsPileupVertex"};
b201705a 482 TString leavesChar[kNvarChar] = {"FiredTrigClass"};
b201705a 483 TString leavesUInt[kNvarUInt] = {"BunchCrossNum", "OrbitNum", "PeriodNum", "RunNum"};
93d6def1 484 TString leavesFloatMC[kNvarFloatMC] = {"PxMC", "PyMC", "PzMC", "PtMC",
485 "EtaMC", "RapidityMC",
486 "VxMC", "VyMC", "VzMC",
487 "MotherPxMC", "MotherPyMC", "MotherPzMC",
488 "MotherEtaMC", "MotherRapidityMC",
489 "MotherVxMC", "MotherVyMC", "MotherVzMC",
490 "IPVxMC", "IPVyMC", "IPVzMC"};
491 TString leavesIntMC[kNvarIntMC] = {"Pdg", "MotherPdg", "MotherType"};
b201705a 492
4ab8d5a6 493 TString treeName = GetOutputSlot(5)->GetContainer()->GetName();
494 Bool_t hasMC = AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler();
495 TString treeTitle = ( hasMC ) ? "Single Mu" : "Single Mu MC";
b201705a 496
4ab8d5a6 497 OpenFile(5);
498 if ( ! fTreeSingleMu ) fTreeSingleMu = new TTree(treeName.Data(), treeTitle.Data());
b201705a 499
500 for(Int_t itree=0; itree<2; itree++){
589e3f71 501 TParameter<Int_t>* par1 = new TParameter<Int_t>("fillTreeScaleDown",fFillTreeScaleDown);
502 TParameter<Int_t>* par2 = new TParameter<Int_t>("keepAllEvents",fKeepAll);
4ab8d5a6 503 fTreeSingleMu->GetUserInfo()->Add(par1);
504 fTreeSingleMu->GetUserInfo()->Add(par2);
b201705a 505 for(Int_t ivar=0; ivar<kNvarFloat; ivar++){
4ab8d5a6 506 fTreeSingleMu->Branch(leavesFloat[ivar].Data(), &fVarFloat[ivar], Form("%s/F", leavesFloat[ivar].Data()));
b201705a 507 }
508 for(Int_t ivar=0; ivar<kNvarInt; ivar++){
4ab8d5a6 509 fTreeSingleMu->Branch(leavesInt[ivar].Data(), &fVarInt[ivar], Form("%s/I", leavesInt[ivar].Data()));
b201705a 510 }
511 for(Int_t ivar=0; ivar<kNvarChar; ivar++){
b201705a 512 TString addString = leavesChar[ivar] + "/C";
4ab8d5a6 513 fTreeSingleMu->Branch(leavesChar[ivar].Data(), fVarChar[ivar], addString.Data());
b201705a 514 }
515 for(Int_t ivar=0; ivar<kNvarUInt; ivar++){
4ab8d5a6 516 fTreeSingleMu->Branch(leavesUInt[ivar].Data(), &fVarUInt[ivar], Form("%s/i", leavesUInt[ivar].Data()));
b201705a 517 }
4ab8d5a6 518 if ( hasMC ){
b201705a 519 for(Int_t ivar=0; ivar<kNvarFloatMC; ivar++){
4ab8d5a6 520 fTreeSingleMu->Branch(leavesFloatMC[ivar].Data(), &fVarFloatMC[ivar], Form("%s/F", leavesFloatMC[ivar].Data()));
b201705a 521 }
522 for(Int_t ivar=0; ivar<kNvarIntMC; ivar++){
4ab8d5a6 523 fTreeSingleMu->Branch(leavesIntMC[ivar].Data(), &fVarIntMC[ivar], Form("%s/I", leavesIntMC[ivar].Data()));
b201705a 524 }
525 }
526 } // loop on trees
4ab8d5a6 527 PostData(5, fTreeSingleMu);
b201705a 528 } // fillNTuple
4ab8d5a6 529
55065f3f 530 PostData(1, fCFManager->GetParticleContainer());
531 PostData(2, fHistoList);
532 PostData(3, fHistoListQA);
4ab8d5a6 533 PostData(4, fHistoListMC);
534
aad6618e 535}
536
537//________________________________________________________________________
9728bcfd 538void AliAnalysisTaskSingleMu::UserExec(Option_t * /*option*/)
aad6618e 539{
540 //
541 /// Main loop
542 /// Called for each event
543 //
544
b201705a 545 AliESDEvent* esdEvent = 0x0;
9728bcfd 546 AliAODEvent* aodEvent = 0x0;
9728bcfd 547
b201705a 548 esdEvent = dynamic_cast<AliESDEvent*> (InputEvent());
549 if ( ! esdEvent ){
b201705a 550 aodEvent = dynamic_cast<AliAODEvent*> (InputEvent());
551 }
aad6618e 552
b201705a 553 if ( ! aodEvent && ! esdEvent ) {
554 AliError ("AOD or ESD event not found. Nothing done!");
aad6618e 555 return;
556 }
557
589e3f71 558 if ( ! fMCEvent && InputEvent()->GetEventType() != 7 ) return; // Run only on physics events!
559
589e3f71 560 Bool_t fillCurrentEventTree = ( fFillTreeScaleDown == 0 ) ? kFALSE : ( Entry() % fFillTreeScaleDown == 0 );
561
562 Reset(kFALSE);
563
564 // Global event info
565 TString firedTrigClasses = ( esdEvent ) ? esdEvent->GetFiredTriggerClasses() : aodEvent->GetFiredTriggerClasses();
4ab8d5a6 566 /*
589e3f71 567 if ( fMCEvent ) {
568 // Add the MB name (which is not there in simulation)
569 // CAVEAT: to be checked if we perform beam-gas simulations
4ab8d5a6 570 if ( ! firedTrigClasses.Contains("CINT") && ! firedTrigClasses.Contains("MB") ) {
571 TString trigName = ((TObjString*)fTriggerClasses->At(0))->GetString();
572 firedTrigClasses.Prepend(Form("%s ", trigName.Data()));
55065f3f 573 }
589e3f71 574 }
4ab8d5a6 575 */
55065f3f 576
93d6def1 577 Double_t centralityValue = InputEvent()->GetCentrality()->GetCentralityPercentile("V0M");
578 // Avoid filling overflow bin when centrality is exactly 100.
579 Double_t centralityForContainer = TMath::Min(centralityValue, 99.999);
580
589e3f71 581 fVarFloat[kVarIPVz] = ( esdEvent ) ? esdEvent->GetPrimaryVertex()->GetZ() : aodEvent->GetPrimaryVertex()->GetZ();
582 fVarInt[kVarNVtxContrib] = ( esdEvent ) ? esdEvent->GetPrimaryVertex()->GetNContributors() : aodEvent->GetPrimaryVertex()->GetNContributors();
583 fVarInt[kVarNspdTracklets] = ( esdEvent ) ? esdEvent->GetMultiplicity()->GetNumberOfTracklets() : aodEvent->GetTracklets()->GetNumberOfTracklets();
55065f3f 584 fVarInt[kVarIsPileup] = ( esdEvent ) ? esdEvent->IsPileupFromSPD(3,0.8) : aodEvent->IsPileupFromSPD(3,0.8); // REMEMBER TO CHECK
589e3f71 585
586 fVarUInt[kVarRunNumber] = ( esdEvent ) ? esdEvent->GetRunNumber() : aodEvent->GetRunNumber();
587
588 Int_t isGoodVtxBin = ( fVarInt[kVarNVtxContrib] >= fkNvtxContribCut );
93d6def1 589 if ( isGoodVtxBin && fVarInt[kVarIsPileup] > 0 )
589e3f71 590 isGoodVtxBin = 2;
591
592 if ( fillCurrentEventTree ){
4ab8d5a6 593 strncpy(fVarChar[kVarTrigMask], firedTrigClasses.Data(),255);
93d6def1 594 fVarFloat[kVarCentrality] = centralityValue;
b201705a 595
589e3f71 596 fVarInt[kVarPassPhysicsSelection] = ( esdEvent ) ? ((AliESDInputHandler*)AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler())->IsEventSelected() : ((AliAODInputHandler*)AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler())->IsEventSelected();
b201705a 597
598 // Small workaround: in MC the bunch ID are not properly set and the timestamp is in seconds
599 // So fill bunchCrossing with the read timestamp
600 // fill the orbit and period number with a timestamp created while reading the run
601 TTimeStamp ts;
589e3f71 602 fVarUInt[kVarBunchCrossNumber] = ( fMCEvent ) ? (UInt_t)Entry() : esdEvent->GetBunchCrossNumber();
603 fVarUInt[kVarOrbitNumber] = ( fMCEvent ) ? ts.GetNanoSec() : esdEvent->GetOrbitNumber();
604 fVarUInt[kVarPeriodNumber] = ( fMCEvent ) ? ts.GetTime() : esdEvent->GetPeriodNumber();
9728bcfd 605
589e3f71 606 fVarFloat[kVarIPVx] = ( esdEvent ) ? esdEvent->GetPrimaryVertex()->GetX() : aodEvent->GetPrimaryVertex()->GetX();
607 fVarFloat[kVarIPVy] = ( esdEvent ) ? esdEvent->GetPrimaryVertex()->GetY() : aodEvent->GetPrimaryVertex()->GetY();
608 }
aad6618e 609
93d6def1 610 firedTrigClasses.Append(" ANY");
611
aad6618e 612 // Object declaration
589e3f71 613 AliMCParticle* mcPart = 0x0;
614 AliVParticle* track = 0x0;
aad6618e 615
589e3f71 616 Double_t containerInput[kNvars];
617 Int_t histoIndex = -1;
b201705a 618
589e3f71 619 fCFManager->SetRecEventInfo(InputEvent());
b201705a 620
589e3f71 621 // Pure Monte Carlo part
622 if ( fMCEvent ) {
623 fCFManager->SetMCEventInfo (fMCEvent);
624 Int_t nMCtracks = fMCEvent->GetNumberOfTracks();
625 if ( nMCtracks > 0 ) {
93d6def1 626 fVarFloatMC[kVarIPVxMC] = fMCEvent->Stack()->Particle(0)->Vx();
627 fVarFloatMC[kVarIPVyMC] = fMCEvent->Stack()->Particle(0)->Vy();
628 fVarFloatMC[kVarIPVzMC] = fMCEvent->Stack()->Particle(0)->Vz();
629 containerInput[kHvarVz] = fVarFloatMC[kVarIPVzMC];
589e3f71 630 containerInput[kHvarIsGoodVtx] = 1;
93d6def1 631 containerInput[kHvarCentrality] = centralityForContainer;
589e3f71 632 histoIndex = GetHistoIndex(kHistoCheckVzMC);
93d6def1 633 ((TH2F*)fHistoListMC->At(histoIndex))->Fill(fVarFloat[kVarIPVz], fVarFloatMC[kVarIPVzMC]);
634 if ( isGoodVtxBin >= 1 ) {
635 histoIndex = GetHistoIndex(kHistoCheckVzHasVtxMC);
636 ((TH2F*)fHistoListMC->At(histoIndex))->Fill(fVarFloat[kVarIPVz], fVarFloatMC[kVarIPVzMC]);
637 }
638 if ( isGoodVtxBin == 1 ) {
639 histoIndex = GetHistoIndex(kHistoCheckVzNoPileupMC);
640 ((TH2F*)fHistoListMC->At(histoIndex))->Fill(fVarFloat[kVarIPVz], fVarFloatMC[kVarIPVzMC]);
641 }
589e3f71 642 }
643
644 for (Int_t ipart=0; ipart<nMCtracks; ipart++) {
645 mcPart = (AliMCParticle*)fMCEvent->GetTrack(ipart);
646
647 //check the MC-level cuts
648 if ( ! fCFManager->CheckParticleCuts(kStepGeneratedMC,mcPart) )
649 continue;
650
651 containerInput[kHvarPt] = mcPart->Pt();
4ab8d5a6 652 //containerInput[kHvarY] = mcPart->Y();
653 containerInput[kHvarEta] = mcPart->Eta();
589e3f71 654 containerInput[kHvarPhi] = mcPart->Phi();
655 containerInput[kHvarDCA] = TMath::Sqrt(mcPart->Xv()*mcPart->Xv() +
656 mcPart->Yv()*mcPart->Yv());
657 containerInput[kHvarThetaZones] = GetBinThetaAbsEnd(TMath::Pi()-mcPart->Theta(),kTRUE);
658 containerInput[kHvarCharge] = mcPart->Charge()/3.;
659 containerInput[kHvarMatchTrig] = 1.;
589e3f71 660 containerInput[kHvarMotherType] = (Double_t)RecoTrackMother(mcPart);
93d6def1 661 //containerInput[kHvarP] = mcPart->P();
589e3f71 662
55065f3f 663 for ( Int_t itrig=0; itrig<fTriggerClasses->GetEntries(); itrig++ ) {
664 TString trigName = ((TObjString*)fTriggerClasses->At(itrig))->GetString();
665 if ( ! firedTrigClasses.Contains(trigName.Data()) )
666 continue;
667 containerInput[kHvarTrigClass] = (Double_t)(itrig+1);
668 fCFManager->GetParticleContainer()->Fill(containerInput,kStepGeneratedMC);
4ab8d5a6 669 // if ( fCFManager->CheckParticleCuts(kStepAcceptanceMC,mcPart) ) fCFManager->GetParticleContainer()->Fill(containerInput,kStepAcceptanceMC);
55065f3f 670 } // loop on trigger classes
93d6def1 671 if ( fDebug >= 2 ) printf("AliAnalysisTaskSingleMu: Pure MC. %s. Set mother %i\n", fDebugString.Data(), (Int_t)containerInput[kHvarMotherType]);
589e3f71 672 } // loop on MC particles
673 } // is MC
674
675
676 Int_t trackLabel = -1;
b201705a 677 Bool_t isGhost = kFALSE;
678 Int_t nGhosts = 0, nMuons = 0;
679
589e3f71 680 Int_t nTracks = ( esdEvent ) ? esdEvent->GetNumberOfMuonTracks() : aodEvent->GetNTracks();
9728bcfd 681
682 for (Int_t itrack = 0; itrack < nTracks; itrack++) {
aad6618e 683
9728bcfd 684 // Get variables
b201705a 685 if ( esdEvent ){
589e3f71 686 // ESD only info
9728bcfd 687
b201705a 688 track = esdEvent->GetMuonTrack(itrack);
689 isGhost = ( ((AliESDMuonTrack*)track)->ContainTriggerData() && ! ((AliESDMuonTrack*)track)->ContainTrackerData() );
690
589e3f71 691 if ( fillCurrentEventTree ) {
692 if ( itrack > 0 ) Reset(kTRUE);
693 fVarFloat[kVarPxUncorrected] = ( isGhost ) ? -TMath::Tan(((AliESDMuonTrack*)track)->GetThetaXUncorrected()) : ((AliESDMuonTrack*)track)->PxUncorrected();
694 fVarFloat[kVarPyUncorrected] = ( isGhost ) ? -TMath::Tan(((AliESDMuonTrack*)track)->GetThetaYUncorrected()) : ((AliESDMuonTrack*)track)->PyUncorrected();
695 fVarFloat[kVarPzUncorrected] = ( isGhost ) ? -1 : ((AliESDMuonTrack*)track)->PzUncorrected();
696
697 fVarFloat[kVarPtUncorrected] =
698 TMath::Sqrt(fVarFloat[kVarPxUncorrected] * fVarFloat[kVarPxUncorrected] +
699 fVarFloat[kVarPyUncorrected] * fVarFloat[kVarPyUncorrected]);
b201705a 700
589e3f71 701 fVarFloat[kVarXUncorrected] = ((AliESDMuonTrack*)track)->GetNonBendingCoorUncorrected();
702 fVarFloat[kVarYUncorrected] = ((AliESDMuonTrack*)track)->GetBendingCoorUncorrected();
703 fVarFloat[kVarZUncorrected] = ((AliESDMuonTrack*)track)->GetZUncorrected();
b201705a 704
589e3f71 705 fVarInt[kVarLocalCircuit] = ((AliESDMuonTrack*)track)->LoCircuit();
706 }
707
708 if ( isGhost ) {
709 // If is ghost fill only a partial information
710 nGhosts++;
711 if ( fillCurrentEventTree ) {
712 fVarInt[kVarIsMuon] = 0;
713 fVarInt[kVarIsGhost] = nGhosts;
714 fVarInt[kVarMatchTrig] = ((AliESDMuonTrack*)track)->GetMatchTrigger();
4ab8d5a6 715 fTreeSingleMu->Fill();
589e3f71 716 }
b201705a 717 continue;
718 }
719 }
720 else {
721 track = aodEvent->GetTrack(itrack);
722 if ( ! ((AliAODTrack*)track)->IsMuonTrack() )
723 continue;
b201705a 724 }
9728bcfd 725
b201705a 726 // Information for tracks in tracker
727 nMuons++;
b201705a 728
729 fVarFloat[kVarPt] = track->Pt();
4ab8d5a6 730 //fVarFloat[kVarRapidity] = track->Y();
731 fVarFloat[kVarEta] = track->Eta();
b201705a 732 fVarFloat[kVarXatDCA] = (esdEvent ) ? ((AliESDMuonTrack*)track)->GetNonBendingCoorAtDCA() : ((AliAODTrack*)track)->XAtDCA();
733 fVarFloat[kVarYatDCA] = (esdEvent ) ? ((AliESDMuonTrack*)track)->GetBendingCoorAtDCA() : ((AliAODTrack*)track)->YAtDCA();
589e3f71 734 fVarFloat[kVarDCA] =
735 TMath::Sqrt( fVarFloat[kVarXatDCA] * fVarFloat[kVarXatDCA] +
736 fVarFloat[kVarYatDCA] * fVarFloat[kVarYatDCA] );
737 fVarFloat[kVarCharge] = (Float_t)track->Charge();
738 fVarFloat[kVarRAtAbsEnd] = (esdEvent ) ? ((AliESDMuonTrack*)track)->GetRAtAbsorberEnd() : ((AliAODTrack*)track)->GetRAtAbsorberEnd();
b201705a 739 fVarInt[kVarMatchTrig] = (esdEvent ) ? ((AliESDMuonTrack*)track)->GetMatchTrigger() : ((AliAODTrack*)track)->GetMatchTrigger();
740
589e3f71 741 if ( fillCurrentEventTree ){
742 fVarInt[kVarIsMuon] = nMuons;
743 fVarInt[kVarIsGhost] = 0;
4ab8d5a6 744 //fVarFloat[kVarEta] = track->Eta();
745 fVarFloat[kVarRapidity] = track->Y();
b201705a 746 fVarFloat[kVarPx] = track->Px();
747 fVarFloat[kVarPy] = track->Py();
748 fVarFloat[kVarPz] = track->Pz();
589e3f71 749 fVarFloat[kVarPxAtDCA] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->PxAtDCA() : ((AliAODTrack*)track)->PxAtDCA();
750 fVarFloat[kVarPyAtDCA] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->PyAtDCA() : ((AliAODTrack*)track)->PyAtDCA();
751 fVarFloat[kVarPzAtDCA] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->PzAtDCA() : ((AliAODTrack*)track)->PzAtDCA();
b201705a 752 fVarFloat[kVarPtAtDCA] = TMath::Sqrt(fVarFloat[kVarPxAtDCA]*fVarFloat[kVarPxAtDCA] + fVarFloat[kVarPyAtDCA]*fVarFloat[kVarPyAtDCA]);
b201705a 753 }
9728bcfd 754
589e3f71 755 fVarIntMC[kVarMotherType] = kUnknownPart;
756
9728bcfd 757 // Monte Carlo part
589e3f71 758 if ( fMCEvent ) {
9728bcfd 759
589e3f71 760 trackLabel = track->GetLabel();
9728bcfd 761
93d6def1 762 if ( trackLabel >= 0 ) {
763 AliMCParticle* matchedMCTrack = (AliMCParticle*)fMCEvent->GetTrack(trackLabel);
589e3f71 764 fVarIntMC[kVarMotherType] = RecoTrackMother(matchedMCTrack);
765 fVarFloatMC[kVarPtMC] = matchedMCTrack->Pt();
766 FillTriggerHistos(kHistoPtResolutionMC, fVarInt[kVarMatchTrig], fVarIntMC[kVarMotherType], fVarFloat[kVarPt] - fVarFloatMC[kVarPtMC]);
767 if ( fillCurrentEventTree ){
768 fVarFloatMC[kVarPxMC] = matchedMCTrack->Px();
769 fVarFloatMC[kVarPyMC] = matchedMCTrack->Py();
770 fVarFloatMC[kVarPzMC] = matchedMCTrack->Pz();
771 fVarFloatMC[kVarEtaMC] = matchedMCTrack->Eta();
772 fVarFloatMC[kVarRapidityMC] = matchedMCTrack->Y();
773 fVarFloatMC[kVarVxMC] = matchedMCTrack->Xv();
774 fVarFloatMC[kVarVyMC] = matchedMCTrack->Yv();
775 fVarFloatMC[kVarVzMC] = matchedMCTrack->Zv();
776 fVarIntMC[kVarPdg] = matchedMCTrack->PdgCode();
93d6def1 777
778 Int_t imother = matchedMCTrack->GetMother();
779 if ( imother >= 0 ) {
780 AliMCParticle* motherTrack = (AliMCParticle*)fMCEvent->GetTrack(imother);
781 fVarFloatMC[kVarMotherPxMC] = motherTrack->Px();
782 fVarFloatMC[kVarMotherPyMC] = motherTrack->Py();
783 fVarFloatMC[kVarMotherPzMC] = motherTrack->Pz();
784 fVarFloatMC[kVarMotherEtaMC] = motherTrack->Eta();
785 fVarFloatMC[kVarMotherRapidityMC] = motherTrack->Y();
786 fVarFloatMC[kVarMotherVxMC] = motherTrack->Xv();
787 fVarFloatMC[kVarMotherVyMC] = motherTrack->Yv();
788 fVarFloatMC[kVarMotherVzMC] = motherTrack->Zv();
789 fVarIntMC[kVarMotherPdg] = motherTrack->PdgCode();
790 }
589e3f71 791 }
b201705a 792 }
93d6def1 793 if ( fDebug >= 1 ) printf("AliAnalysisTaskSingleMu: Reco track. %s. Set mother %i\n", fDebugString.Data(), fVarIntMC[kVarMotherType]);
589e3f71 794 } // if use MC
795
796 containerInput[kHvarPt] = fVarFloat[kVarPt];
4ab8d5a6 797 //containerInput[kHvarY] = fVarFloat[kVarRapidity];
798 containerInput[kHvarEta] = fVarFloat[kVarEta];
589e3f71 799 containerInput[kHvarPhi] = track->Phi();
800 containerInput[kHvarDCA] = fVarFloat[kVarDCA];
801 containerInput[kHvarVz] = fVarFloat[kVarIPVz];
802 containerInput[kHvarThetaZones] = GetBinThetaAbsEnd(fVarFloat[kVarRAtAbsEnd]);
803 containerInput[kHvarCharge] = fVarFloat[kVarCharge];
804 containerInput[kHvarMatchTrig] = (Double_t)fVarInt[kVarMatchTrig];
589e3f71 805 containerInput[kHvarIsGoodVtx] = (Double_t)isGoodVtxBin;
806 containerInput[kHvarMotherType] = (Double_t)fVarIntMC[kVarMotherType];
93d6def1 807 containerInput[kHvarCentrality] = centralityForContainer;
808 //containerInput[kHvarP] = track->P();
589e3f71 809
55065f3f 810 histoIndex = GetHistoIndex(kHistoNmuonsPerRun);
811 for ( Int_t itrig=0; itrig<fTriggerClasses->GetEntries(); itrig++ ) {
812 TString trigName = ((TObjString*)fTriggerClasses->At(itrig))->GetString();
813 if ( ! firedTrigClasses.Contains(trigName.Data()) )
814 continue;
815 containerInput[kHvarTrigClass] = (Double_t)(itrig+1);
816 fCFManager->GetParticleContainer()->Fill(containerInput,kStepReconstructed);
4ab8d5a6 817 // if ( fCFManager->CheckParticleCuts(kStepAcceptance,track) ) fCFManager->GetParticleContainer()->Fill(containerInput,kStepAcceptance);
55065f3f 818 ((TH2F*)fHistoList->At(histoIndex))->Fill(Form("%u",fVarUInt[kVarRunNumber]), containerInput[kHvarTrigClass], 1.);
819 } // loop on trigger classes
589e3f71 820
4ab8d5a6 821 if ( fillCurrentEventTree ) fTreeSingleMu->Fill();
9728bcfd 822 } // loop on tracks
b201705a 823
589e3f71 824 if ( fillCurrentEventTree && fKeepAll && ( ( nMuons + nGhosts ) == 0 ) ) {
b201705a 825 // Fill event also if there is not muon (when explicitely required)
4ab8d5a6 826 fTreeSingleMu->Fill();
b201705a 827 }
828
55065f3f 829 for ( Int_t itrig=0; itrig<fTriggerClasses->GetEntries(); itrig++ ) {
830 TString trigName = ((TObjString*)fTriggerClasses->At(itrig))->GetString();
831 if ( ! firedTrigClasses.Contains(trigName.Data()) )
832 continue;
833 Double_t trigClassBin = (Double_t)(itrig+1);
834 histoIndex = GetHistoIndex(kHistoNeventsPerTrig);
835 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 1., 1.); // All events
836 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 4., (Double_t)(fVarInt[kVarIsPileup]+1)); // All vertices
837 if ( isGoodVtxBin == 1 )
838 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 2., 1.); // Good vtx events
839 else if ( isGoodVtxBin == 2 ) {
840 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 3., 1.); // Pileup events
841 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 5., 1.); // Pileup vertices
842 }
589e3f71 843
55065f3f 844 histoIndex = GetHistoIndex(kHistoMuonMultiplicity);
845 ((TH1F*)fHistoList->At(histoIndex))->Fill(nMuons, trigClassBin);
589e3f71 846
4ab8d5a6 847 if ( isGoodVtxBin == 1 ) {
55065f3f 848 histoIndex = GetHistoIndex(kHistoEventVz);
4ab8d5a6 849 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin,fVarFloat[kVarIPVz]);
55065f3f 850 }
851
852 histoIndex = GetHistoIndex(kHistoNeventsPerRun);
853 ((TH2F*)fHistoList->At(histoIndex))->Fill(Form("%u",fVarUInt[kVarRunNumber]), trigClassBin, 1.);
854 } // loop on trigger classes
589e3f71 855
589e3f71 856
857 // Post final data. It will be written to a file with option "RECREATE"
858 PostData(1, fCFManager->GetParticleContainer());
859 PostData(2, fHistoList);
55065f3f 860 PostData(3, fHistoListQA);
4ab8d5a6 861 PostData(4, fHistoListMC);
589e3f71 862 if ( fFillTreeScaleDown > 0 )
4ab8d5a6 863 PostData(5, fTreeSingleMu);
aad6618e 864}
865
866//________________________________________________________________________
867void AliAnalysisTaskSingleMu::Terminate(Option_t *) {
868 //
869 /// Draw some histogram at the end.
870 //
589e3f71 871
872 AliCFContainer* container = dynamic_cast<AliCFContainer*> (GetOutputData(1));
873 if ( ! container ) {
874 AliError("Cannot find container in file");
875 return;
876 }
877
878 //Int_t histoIndex = -1;
879
880 if ( ! gROOT->IsBatch() ) {
4ab8d5a6 881 TString currName = GetName();
882 currName.Prepend("c1_");
883 TCanvas *c1_SingleMu = new TCanvas(currName.Data(),"Vz vs Pt",10,10,310,310);
93fd3322 884 c1_SingleMu->SetFillColor(10); c1_SingleMu->SetHighLightColor(10);
885 c1_SingleMu->SetLeftMargin(0.15); c1_SingleMu->SetBottomMargin(0.15);
93d6def1 886 TH2* histo = dynamic_cast<TH2*>(container->Project(kStepReconstructed,kHvarPt,kHvarVz));
4ab8d5a6 887 currName = GetName();
888 currName.Prepend("hPtVz_");
889 histo->SetName(currName.Data());
890 histo->Draw("COLZ");
aad6618e 891 }
589e3f71 892
aad6618e 893}
894
895//________________________________________________________________________
9728bcfd 896 void AliAnalysisTaskSingleMu::FillTriggerHistos(Int_t histoIndex, Int_t matchTrig, Int_t motherType,
897 Float_t var1, Float_t var2, Float_t var3)
aad6618e 898{
899 //
9728bcfd 900 /// Fill all histograms passing the trigger cuts
aad6618e 901 //
662e37fe 902
9728bcfd 903 Int_t nTrigs = TMath::Max(1, matchTrig);
904 TArrayI trigToFill(nTrigs);
905 trigToFill[0] = matchTrig;
906 for(Int_t itrig = 1; itrig < matchTrig; itrig++){
907 trigToFill[itrig] = itrig;
908 }
662e37fe 909
9728bcfd 910 TList* histoList = (motherType < 0 ) ? fHistoList : fHistoListMC;
911
912 TString className;
913 for(Int_t itrig = 0; itrig < nTrigs; itrig++){
914 Int_t currIndex = GetHistoIndex(histoIndex, trigToFill[itrig], motherType);
915 className = histoList->At(currIndex)->ClassName();
93d6def1 916 if ( fDebug >= 3 ) printf("AliAnalysisTaskSingleMu: matchTrig %i Fill %s\n", matchTrig, histoList->At(currIndex)->GetName());
9728bcfd 917 if (className.Contains("1"))
918 ((TH1F*)histoList->At(currIndex))->Fill(var1);
919 else if (className.Contains("2"))
920 ((TH2F*)histoList->At(currIndex))->Fill(var1, var2);
921 else if (className.Contains("3"))
922 ((TH3F*)histoList->At(currIndex))->Fill(var1, var2, var3);
923 else
924 AliWarning("Histogram not filled");
925 }
aad6618e 926}
927
aad6618e 928//________________________________________________________________________
589e3f71 929Int_t AliAnalysisTaskSingleMu::RecoTrackMother(AliMCParticle* mcParticle)
aad6618e 930{
931 //
9728bcfd 932 /// Find track mother from kinematics
aad6618e 933 //
934
589e3f71 935 Int_t recoPdg = mcParticle->PdgCode();
aad6618e 936
93d6def1 937 fDebugString = Form("History: %i", recoPdg);
938
9728bcfd 939 // Track is not a muon
589e3f71 940 if ( TMath::Abs(recoPdg) != 13 ) return kRecoHadron;
aad6618e 941
589e3f71 942 Int_t imother = mcParticle->GetMother();
aad6618e 943
93d6def1 944 //Int_t baseFlv[2] = {4,5};
945 //Int_t mType[2] = {kCharmMu, kBeautyMu};
946 Int_t den[3] = {100, 1000, 1};
aad6618e 947
93d6def1 948 //Bool_t isFirstMotherHF = kFALSE;
949 //Int_t step = 0;
950 Int_t motherType = kPrimaryMu;
589e3f71 951 while ( imother >= 0 ) {
952 TParticle* part = ((AliMCParticle*)fMCEvent->GetTrack(imother))->Particle();
662e37fe 953
93d6def1 954 fDebugString += Form(" <- %s (%s)", part->GetName(), TMCProcessName[part->GetUniqueID()]);
662e37fe 955
589e3f71 956 Int_t absPdg = TMath::Abs(part->GetPdgCode());
93d6def1 957 //step++;
958
959 if ( imother < fMCEvent->GetNumberOfPrimaries() ) {
960 /*
961 // Hadronic processes are not possible for "primary" =>
962 // either is decay or HF
963 if ( absPdg > 100 && absPdg < 400 ) {
964 // it is decay mu
965 motherType = kPrimaryMu;
966 break; // particle loop
967 }
968 else if ( step == 1 || isFirstMotherHF ){
969 // Check if it is HF muon
970 // avoid the case when the HF was not the first mother
971 // (the mu is produced by a decain chain => decay mu)
972 Bool_t foundHF = kFALSE;
973 for ( Int_t idec=0; idec<3; idec++ ) {
974 for ( Int_t ihf=0; ihf<2; ihf++ ) {
975 if ( ( absPdg/den[idec] ) != baseFlv[ihf] ) continue;
976 motherType = mType[ihf];
977 foundHF = kTRUE;
978 break;
979 } // loop on hf
980 if ( foundHF ) {
981 if ( step == 1 ) isFirstMotherHF = kTRUE;
982 break; // break loop on pdg code
983 // but continue the global loop to find higher mass HF
984 }
985 } // loop on pdg codes
986 if ( ! foundHF ) {
987 motherType = kPrimaryMu;
988 break;
989 }
990 else if ( absPdg < 10 ) {
991 // found HF quark: break particle loop
992 break;
993 }
994 } // potential HF code
995 */
996 for ( Int_t idec=0; idec<3; idec++ ) {
997 Int_t flv = absPdg/den[idec];
998 if ( flv > 0 && flv < 4 ) return kPrimaryMu;
999 else if ( flv == 0 || flv > 5 ) continue;
1000 else {
1001 motherType = ( flv == 4 ) ? kCharmMu : kBeautyMu;
1002 break; // break loop on pdg code
1003 // but continue the global loop to find higher mass HF
1004 }
1005 } // loop on pdg code
1006 if ( absPdg < 10 ) break; // particle loop
1007 } // is primary
1008 else {
1009 // If hadronic process => secondary
1010 if ( part->GetUniqueID() == kPHadronic ) {
1011 //motherType = kSecondaryMu;
1012 //break; // particle loop
1013 return kSecondaryMu;
1014 }
1015 } // is secondary
9728bcfd 1016
589e3f71 1017 imother = part->GetFirstMother();
9728bcfd 1018
93d6def1 1019 } // loop on mothers
1020
1021 return motherType;
589e3f71 1022}
662e37fe 1023
589e3f71 1024//________________________________________________________________________
1025Int_t AliAnalysisTaskSingleMu::GetHistoIndex(Int_t histoTypeIndex, Int_t trigIndex, Int_t srcIndex)
1026{
1027 //
1028 /// Get histogram index in the list
1029 //
1030
1031 if ( srcIndex < 0 ) {
1032 return histoTypeIndex;
9728bcfd 1033 }
589e3f71 1034
1035 return
1036 kNsummaryHistosMC +
1037 kNtrackSources * kNtrigCuts * histoTypeIndex +
1038 kNtrackSources * trigIndex +
1039 srcIndex;
9728bcfd 1040}
662e37fe 1041
9728bcfd 1042//________________________________________________________________________
589e3f71 1043Float_t AliAnalysisTaskSingleMu::GetBinThetaAbsEnd(Float_t RAtAbsEnd, Bool_t isTheta)
1044{
1045 //
1046 /// Get bin of theta at absorber end region
1047 //
1048 Float_t thetaDeg = ( isTheta ) ? RAtAbsEnd : TMath::ATan( RAtAbsEnd / 505. );
1049 thetaDeg *= TMath::RadToDeg();
1050 if ( thetaDeg < 2. )
1051 return 0.;
1052 else if ( thetaDeg < 3. )
1053 return 1.;
1054 else if ( thetaDeg < 9. )
1055 return 2.;
1056
1057 return 3.;
1058}
1059
b201705a 1060
1061//________________________________________________________________________
1062void AliAnalysisTaskSingleMu::Reset(Bool_t keepGlobal)
1063{
1064 //
1065 /// Reset variables
1066 //
1067 Int_t lastVarFloat = ( keepGlobal ) ? kVarIPVx : kNvarFloat;
1068 for(Int_t ivar=0; ivar<lastVarFloat; ivar++){
1069 fVarFloat[ivar] = 0.;
1070 }
1071 Int_t lastVarInt = ( keepGlobal ) ? kVarPassPhysicsSelection : kNvarInt;
1072 for(Int_t ivar=0; ivar<lastVarInt; ivar++){
589e3f71 1073 fVarInt[ivar] = 0;
b201705a 1074 }
589e3f71 1075 fVarInt[kVarMatchTrig] = -1;
b201705a 1076
1077 if ( ! keepGlobal ){
1078 for(Int_t ivar=0; ivar<kNvarChar; ivar++){
4ab8d5a6 1079 strncpy(fVarChar[ivar]," ",255);
b201705a 1080 }
1081 for(Int_t ivar=0; ivar<kNvarUInt; ivar++){
1082 fVarUInt[ivar] = 0;
1083 }
1084 }
589e3f71 1085 if ( fMCEvent ){
93d6def1 1086 lastVarFloat = ( keepGlobal ) ? kVarIPVxMC : kNvarFloatMC;
1087 for(Int_t ivar=0; ivar<lastVarFloat; ivar++){
b201705a 1088 fVarFloatMC[ivar] = 0.;
1089 }
1090 for(Int_t ivar=0; ivar<kNvarIntMC; ivar++){
93d6def1 1091 fVarIntMC[ivar] = 0;
b201705a 1092 }
93d6def1 1093 fVarIntMC[kVarMotherType] = -1;
1094 }
b201705a 1095}
589e3f71 1096
1097//________________________________________________________________________
55065f3f 1098void AliAnalysisTaskSingleMu::SetTriggerClasses(TString triggerClasses)
589e3f71 1099{
55065f3f 1100 /// Set trigger classes
1101 if ( fTriggerClasses )
1102 delete fTriggerClasses;
1103
1104 fTriggerClasses = triggerClasses.Tokenize(" ");
1105 fTriggerClasses->SetOwner();
589e3f71 1106
55065f3f 1107}
589e3f71 1108
1109//________________________________________________________________________
1110void AliAnalysisTaskSingleMu::SetAxisLabel(TAxis* axis)
1111{
1112 //
1113 /// Set the labels of trigger class axis
1114 //
55065f3f 1115 for ( Int_t itrig=0; itrig<fTriggerClasses->GetEntries(); itrig++ ) {
1116 TString trigName = ((TObjString*)fTriggerClasses->At(itrig))->GetString();
1117 axis->SetBinLabel(itrig+1,trigName.Data());
1118 }
1119 axis->SetTitle("Fired class");
589e3f71 1120}