1 /**************************************************************************
2 * Copyright(c) 1998-2007, 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 AliAnalysisTaskSingleMu
20 /// Analysis task for single muons in the spectrometer.
21 /// The output is a list of histograms.
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.
24 /// If Monte Carlo information is present, some basics checks are performed.
26 /// \author Diego Stocco
27 //-----------------------------------------------------------------------------
29 //----------------------------------------------------------------------------
30 // Implementation of the single muon analysis class
31 // An example of usage can be found in the macro RunSingleMuAnalysisFromAOD.C.
32 //----------------------------------------------------------------------------
34 #define AliAnalysisTaskSingleMu_cxx
46 #include "TTimeStamp.h"
48 #include "TObjString.h"
49 #include "TObjArray.h"
50 #include "TIterator.h"
51 #include "TParameter.h"
52 #include "TMCProcess.h"
55 #include "AliInputEventHandler.h"
56 #include "AliVVertex.h"
57 #include "AliMultiplicity.h"
58 #include "AliCentrality.h"
60 //#include "AliAODInputHandler.h"
61 #include "AliAODEvent.h"
62 #include "AliAODTrack.h"
63 //#include "AliAODVertex.h"
65 #include "AliMCEvent.h"
66 #include "AliMCParticle.h"
69 //#include "AliESDInputHandler.h"
70 #include "AliESDEvent.h"
71 #include "AliESDMuonTrack.h"
74 #include "AliAnalysisManager.h"
75 #include "AliAnalysisTaskSE.h"
76 #include "AliAnalysisDataSlot.h"
77 #include "AliAnalysisDataContainer.h"
80 #include "AliCFManager.h"
81 #include "AliCFContainer.h"
82 #include "AliCFGridSparse.h"
83 #include "AliCFTrackKineCuts.h"
84 #include "AliCFParticleGenCuts.h"
85 #include "AliCFEventRecCuts.h"
87 #include "AliAnalysisTaskSingleMu.h"
90 ClassImp(AliAnalysisTaskSingleMu) // Class implementation in ROOT context
94 //________________________________________________________________________
95 AliAnalysisTaskSingleMu::AliAnalysisTaskSingleMu(const char *name, Int_t fillTreeScaleDown, Bool_t keepAll) :
96 AliAnalysisTaskSE(name),
97 fFillTreeScaleDown(fillTreeScaleDown),
100 fTriggerClasses(0x0),
112 fAuxObjects(new TMap()),
118 if ( fFillTreeScaleDown <= 0 )
121 DefineOutput(1, AliCFContainer::Class());
122 DefineOutput(2, TList::Class());
123 DefineOutput(3, TList::Class());
124 DefineOutput(4, TList::Class());
126 if ( fFillTreeScaleDown > 0 )
127 DefineOutput(5, TTree::Class());
129 fAuxObjects->SetOwner();
135 //________________________________________________________________________
136 AliAnalysisTaskSingleMu::~AliAnalysisTaskSingleMu()
142 delete fTriggerClasses;
143 // For proof: do not delete output containers
144 if ( ! AliAnalysisManager::GetAnalysisManager() || ! AliAnalysisManager::GetAnalysisManager()->IsProofMode() ) {
145 // In terminate mode fCFManager does not exist!
146 // So, check before deleting
148 delete fCFManager->GetParticleContainer(); // The container is not deleted by framework
153 delete fTreeSingleMu;
165 //___________________________________________________________________________
166 void AliAnalysisTaskSingleMu::NotifyRun()
169 /// Use the event handler information to correctly fill the analysis flags:
170 /// - check if Monte Carlo information is present
174 AliInfo("Monte Carlo information is present");
177 AliInfo("No Monte Carlo information in run");
182 //___________________________________________________________________________
183 void AliAnalysisTaskSingleMu::FinishTaskOutput()
186 /// Perform histogram normalization after the last analyzed event
187 /// but before merging
190 // Set the correct run limits for the histograms
191 // vs run number to cope with the merging
192 Int_t histoIndex = -1;
193 Int_t indexPerRun[2] = {kHistoNeventsPerRun, kHistoNmuonsPerRun};
194 for ( Int_t ihisto=0; ihisto<2; ihisto++) {
195 histoIndex = GetHistoIndex(indexPerRun[ihisto]);
196 TH2F* histo2D = (TH2F*)fHistoList->At(histoIndex);
197 Double_t minX = 1e10, maxX = -1e10;
198 for (Int_t ibin=1; ibin<=histo2D->GetXaxis()->GetNbins(); ibin++){
199 TString runNum = histo2D->GetXaxis()->GetBinLabel(ibin);
200 minX = TMath::Min(runNum.Atof()-0.5, minX);
201 maxX = TMath::Max(runNum.Atof()+0.5, maxX);
203 histo2D->GetXaxis()->SetLimits(minX, maxX);
204 AliInfo(Form("Histogram %s run limits (%f, %f)",histo2D->GetName(), minX, maxX));
207 // Add stat. info from physics selection
208 // (usefull when running on AODs)
209 TString histoName = "";
210 if ( fInputHandler ) {
211 for ( Int_t istat=0; istat<2; istat++ ) {
212 TString statType = ( istat == 0 ) ? "ALL" : "BIN0";
213 TH2* hStat = dynamic_cast<TH2*>(fInputHandler->GetStatistics(statType.Data()));
215 histoName = Form("%s_SingleMuon", hStat->GetName());
216 TH2* cloneStat = static_cast<TH2*>(hStat->Clone(histoName.Data()));
217 cloneStat->SetDirectory(0);
218 fHistoList->Add(cloneStat);
221 AliWarning("Stat histogram not available");
224 } // loop on stat type
229 //___________________________________________________________________________
230 void AliAnalysisTaskSingleMu::UserCreateOutputObjects()
233 /// Create output histograms
235 AliInfo(Form(" CreateOutputObjects of task %s\n", GetName()));
237 // initialize histogram lists
238 fHistoList = new TList();
239 fHistoList->SetOwner();
240 fHistoListMC = new TList();
241 fHistoListMC->SetOwner();
242 fHistoListQA = new TList();
243 fHistoListQA->SetOwner();
246 fVarFloat = new Float_t [kNvarFloat];
247 fVarInt = new Int_t [kNvarInt];
248 fVarChar = new Char_t *[kNvarChar];
249 fVarUInt = new UInt_t [kNvarUInt];
250 fVarFloatMC = new Float_t [kNvarFloatMC];
251 fVarIntMC = new Int_t [kNvarIntMC];
253 const Int_t charWidth[kNvarChar] = {255};
254 for(Int_t ivar=0; ivar<kNvarChar; ivar++){
255 fVarChar[ivar] = new Char_t [charWidth[ivar]];
258 Int_t nPtBins = 60; //200; //60;
259 Double_t ptMin = 0., ptMax = 30.; //100.; //30.; // extend range for z
260 TString ptName("Pt"), ptTitle("p_{t}"), ptUnits("GeV/c");
262 Int_t nRapidityBins = 25;
263 Double_t rapidityMin = -4.5, rapidityMax = -2.;
264 //TString rapidityName("Rapidity"), rapidityTitle("y"), rapidityUnits("");
265 TString rapidityName("Eta"), rapidityTitle("#eta"), rapidityUnits("");
268 Double_t phiMin = 0.; Double_t phiMax = 2*TMath::Pi();
269 TString phiName("Phi"), phiTitle("#phi"), phiUnits("rad");
272 Double_t dcaMin = 0., dcaMax = 300.;
273 TString dcaName("DCA"), dcaTitle("DCA"), dcaUnits("cm");
276 Double_t vzMin = -20., vzMax = 20.;
277 TString vzName("Vz"), vzTitle("Vz"), vzUnits("cm");
279 Int_t nThetaAbsEndBins = 4;
280 Double_t thetaAbsEndMin = -0.5, thetaAbsEndMax = 3.5;
281 TString thetaAbsEndName("ThetaAbsEnd"), thetaAbsEndTitle("#theta_{abs}"), thetaAbsEndUnits("a.u.");
283 Int_t nChargeBins = 2;
284 Double_t chargeMin = -2, chargeMax = 2.;
285 TString chargeName("Charge"), chargeTitle("charge"), chargeUnits("e");
287 Int_t nMatchTrigBins = 4;
288 Double_t matchTrigMin = -0.5, matchTrigMax = 3.5;
289 TString matchTrigName("MatchTrig"), matchTrigTitle("Trigger match"), matchTrigUnits("");
291 Int_t nTrigClassBins = fTriggerClasses->GetEntries();
292 Double_t trigClassMin = 0.5, trigClassMax = (Double_t)nTrigClassBins + 0.5;
293 TString trigClassName("TrigClass"), trigClassTitle("Fired trigger class"), trigClassUnits("");
295 Int_t nGoodVtxBins = 3;
296 Double_t goodVtxMin = -0.5, goodVtxMax = 2.5;
297 TString goodVtxName("GoodVtx"), goodVtxTitle("Vertex flags"), goodVtxUnits("");
299 Int_t nMotherTypeBins = kNtrackSources;
300 Double_t motherTypeMin = -0.5, motherTypeMax = (Double_t)kNtrackSources - 0.5;
301 TString motherType("MotherType"), motherTypeTitle("motherType"), motherTypeUnits("");
303 Int_t nCentralityBins = 12;
304 Double_t centralityMin = -10., centralityMax = 110.;
305 TString centralityName("Centrality"), centralityTitle("centrality"), centralityUnits("%");
307 TString trigName[kNtrigCuts];
308 trigName[kNoMatchTrig] = "NoMatch";
309 trigName[kAllPtTrig] = "AllPt";
310 trigName[kLowPtTrig] = "LowPt";
311 trigName[kHighPtTrig] = "HighPt";
313 TString srcName[kNtrackSources];
314 srcName[kCharmMu] = "Charm";
315 srcName[kBeautyMu] = "Beauty";
316 srcName[kPrimaryMu] = "Decay";
317 srcName[kSecondaryMu] = "Secondary";
318 srcName[kRecoHadron] = "Hadrons";
319 srcName[kUnknownPart] = "Unidentified";
323 TString histoName, histoTitle;
324 Int_t histoIndex = 0;
326 // Multi-dimensional histo
327 Int_t nbins[kNvars] = {nPtBins, nRapidityBins, nPhiBins, nDcaBins, nVzBins, nThetaAbsEndBins, nChargeBins, nMatchTrigBins, nTrigClassBins, nGoodVtxBins, nMotherTypeBins, nCentralityBins};
328 Double_t xmin[kNvars] = {ptMin, rapidityMin, phiMin, dcaMin, vzMin, thetaAbsEndMin, chargeMin, matchTrigMin, trigClassMin, goodVtxMin, motherTypeMin, centralityMin};
329 Double_t xmax[kNvars] = {ptMax, rapidityMax, phiMax, dcaMax, vzMax, thetaAbsEndMax, chargeMax, matchTrigMax, trigClassMax, goodVtxMax, motherTypeMax, centralityMax};
330 TString axisTitle[kNvars] = {ptTitle, rapidityTitle, phiTitle, dcaTitle, vzTitle, thetaAbsEndTitle, chargeTitle, matchTrigTitle, trigClassTitle, goodVtxTitle, motherTypeTitle, centralityTitle};
331 TString axisUnits[kNvars] = {ptUnits, rapidityUnits, phiUnits, dcaUnits, vzUnits, thetaAbsEndUnits, chargeUnits, matchTrigUnits, trigClassUnits, goodVtxUnits, motherTypeUnits, centralityUnits};
333 //TString stepTitle[kNsteps] = {"reconstructed", "in acceptance", "generated", "in acceptance (MC)"};
334 TString stepTitle[kNsteps] = {"reconstructed", "generated"};
336 // Create CF container
338 // The framework has problems if the name of the object
339 // and the one of container differ
340 // To be complaint, get the name from container and set it
341 TString containerName = GetOutputSlot(1)->GetContainer()->GetName();
343 AliCFContainer* container = new AliCFContainer(containerName.Data(),"container for tracks",kNsteps,kNvars,nbins);
345 for ( Int_t idim = 0; idim<kNvars; idim++){
346 histoTitle = Form("%s (%s)", axisTitle[idim].Data(), axisUnits[idim].Data());
347 histoTitle.ReplaceAll("()","");
349 container->SetVarTitle(idim, histoTitle.Data());
350 container->SetBinLimits(idim, xmin[idim], xmax[idim]);
353 for (Int_t istep=0; istep<kNsteps; istep++){
354 container->SetStepTitle(istep, stepTitle[istep].Data());
355 AliCFGridSparse* gridSparse = container->GetGrid(istep);
357 SetAxisLabel(gridSparse->GetAxis(kHvarTrigClass));
358 TAxis* isGoodVtxAxis = gridSparse->GetAxis(kHvarIsGoodVtx);
359 isGoodVtxAxis->SetBinLabel(1,Form("No vertex (contrib<%i)",fkNvtxContribCut));
360 isGoodVtxAxis->SetBinLabel(2,"Good vertex");
361 isGoodVtxAxis->SetBinLabel(3,"Pileup");
362 TAxis* motherTypeAxis = gridSparse->GetAxis(kHvarMotherType);
363 for (Int_t ibin=0; ibin<kNtrackSources; ibin++){
364 motherTypeAxis->SetBinLabel(ibin+1,srcName[ibin]);
370 //Particle-Level cuts:
371 AliCFParticleGenCuts* mcGenCuts = new AliCFParticleGenCuts();
372 mcGenCuts->SetNameTitle("mcGenCuts","MC particle generation cuts");
373 mcGenCuts->SetRequirePdgCode(13,kTRUE);
374 mcGenCuts->SetQAOn(fHistoListQA);
378 AliCFTrackKineCuts *mcAccCuts = new AliCFTrackKineCuts();
379 mcAccCuts->SetNameTitle("mcAccCuts","MC-level acceptance cuts");
380 mcAccCuts->SetEtaRange(-4.,-2.5);
381 mcAccCuts->SetQAOn(fHistoListQA);
383 // Rec-Level kinematic cuts
384 AliCFTrackKineCuts *recAccCuts = new AliCFTrackKineCuts();
385 recAccCuts->SetNameTitle("recAccCuts","Reco-level acceptance cuts");
386 recAccCuts->SetEtaRange(-4.,-2.5);
387 recAccCuts->SetQAOn(fHistoListQA);
390 TObjArray* mcGenList = new TObjArray(0) ;
391 mcGenList->AddLast(mcGenCuts);
394 TObjArray* mcAccList = new TObjArray(0);
395 mcAccList->AddLast(mcAccCuts);
397 TObjArray* recAccList = new TObjArray(0);
398 recAccList->AddLast(recAccCuts);
402 fCFManager = new AliCFManager() ;
403 fCFManager->SetParticleContainer(container);
406 // Dummy event container
407 Int_t dummyBins[1] = {1};
408 AliCFContainer* evtContainer = new AliCFContainer("dummyContainer","dummy contaier for events",1,1,dummyBins);
409 fCFManager->SetEventContainer(evtContainer);
410 fCFManager->SetEventCutsList(0,0x0);
412 // Init empty cuts (avoid warnings in framework)
413 for (Int_t istep=0; istep<kNsteps; istep++) {
414 fCFManager->SetParticleCutsList(istep,0x0);
416 //fCFManager->SetParticleCutsList(kStepAcceptance,recAccList);
417 fCFManager->SetParticleCutsList(kStepGeneratedMC,mcGenList);
418 //fCFManager->SetParticleCutsList(kStepAcceptanceMC,mcAccList);
421 histoName = "histoNeventsPerTrig";
422 histoTitle = "Number of events per trigger class";
423 histo2D = new TH2F(histoName.Data(), histoTitle.Data(), nTrigClassBins, trigClassMin, trigClassMax, 5, 0.5, 5.5);
424 histo2D->GetXaxis()->SetTitle("Fired class");
425 SetAxisLabel(histo2D->GetXaxis());
426 histo2D->GetYaxis()->SetBinLabel(1, "All events");
427 histo2D->GetYaxis()->SetBinLabel(2, "Good vtx events");
428 histo2D->GetYaxis()->SetBinLabel(3, "Pileup events");
429 histo2D->GetYaxis()->SetBinLabel(4, "All vertices");
430 histo2D->GetYaxis()->SetBinLabel(5, "Pileup vertices");
431 histoIndex = GetHistoIndex(kHistoNeventsPerTrig);
432 fHistoList->AddAt(histo2D, histoIndex);
434 histoName = "histoMuonMultiplicity";
435 histoTitle = "Muon track multiplicity";
436 histo2D = new TH2F(histoName.Data(), histoTitle.Data(), 15, -0.5, 15-0.5,
437 nTrigClassBins, trigClassMin, trigClassMax);
438 histo2D->GetXaxis()->SetTitle("# of muons");
439 SetAxisLabel(histo2D->GetYaxis());
440 histoIndex = GetHistoIndex(kHistoMuonMultiplicity);
441 fHistoList->AddAt(histo2D, histoIndex);
443 histoName = "histoEventVz";
444 histoTitle = "All events IP Vz distribution";
445 histo2D = new TH2F(histoName.Data(), histoTitle.Data(), nTrigClassBins, trigClassMin, trigClassMax, nVzBins, vzMin, vzMax);
446 histo2D->GetXaxis()->SetTitle("Fired class");
447 SetAxisLabel(histo2D->GetXaxis());
448 histoTitle = Form("%s (%s)", vzTitle.Data(), vzUnits.Data());
449 histo2D->GetYaxis()->SetTitle(histoTitle.Data());
450 histoIndex = GetHistoIndex(kHistoEventVz);
451 fHistoList->AddAt(histo2D, histoIndex);
453 Int_t hRunIndex[2] = {kHistoNeventsPerRun, kHistoNmuonsPerRun};
454 TString hRunName[2] = {"histoNeventsPerRun", "histoNmuonsPerRun"};
455 TString hRunTitle[2] = {"Number of events per run", "Number of muons per run"};
456 for ( Int_t ihisto=0; ihisto<2; ihisto++){
457 histoName = hRunName[ihisto];
458 histoTitle = hRunTitle[ihisto];
459 histo2D = new TH2F(histoName.Data(), histoTitle.Data(),
461 nTrigClassBins, trigClassMin, trigClassMax);
462 histo2D->GetXaxis()->SetTitle("Run number");
463 SetAxisLabel(histo2D->GetYaxis());
465 histoIndex = hRunIndex[ihisto];
466 fHistoList->AddAt(histo2D, histoIndex);
470 Int_t hCheckVzIndex[3] = {kHistoCheckVzMC, kHistoCheckVzHasVtxMC, kHistoCheckVzNoPileupMC};
471 TString hCheckVzName[3] = {"histoCheckVz", "histoCheckVzHasVtx", "histoCheckVzIsPileup"};
472 TString hCheckVzTitle[3] = {"", " w/ vertex contributors", "w/ pileup SPD"};
474 for ( Int_t ihisto=0; ihisto<3; ihisto++ ) {
475 histoName = hCheckVzName[ihisto];
476 histoTitle = Form("Check IP Vz distribution %s", hCheckVzTitle[ihisto].Data());
478 histo2D = new TH2F(histoName.Data(), histoTitle.Data(),
479 nVzBins, vzMin, vzMax,
480 nVzBins, vzMin, vzMax);
481 histoTitle = Form("%s (%s)", vzTitle.Data(), vzUnits.Data());
482 histo2D->GetXaxis()->SetTitle(histoTitle.Data());
483 histoTitle = Form("%s MC (%s)", vzTitle.Data(), vzUnits.Data());
484 histo2D->GetYaxis()->SetTitle(histoTitle.Data());
485 histoIndex = GetHistoIndex(hCheckVzIndex[ihisto]);
486 fHistoListMC->AddAt(histo2D, histoIndex);
490 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
491 for (Int_t isrc = 0; isrc < kNtrackSources; isrc++) {
492 histoName = Form("%sResolution%sTrig%s", ptName.Data(), trigName[itrig].Data(), srcName[isrc].Data());
493 histoTitle = Form("%s resolution. Trigger: %s (%s)", ptTitle.Data(), trigName[itrig].Data(), srcName[isrc].Data());
494 histo1D = new TH1F(histoName.Data(), histoTitle.Data(), 100, -5., 5.);
495 histo1D->GetXaxis()->SetTitle(Form("%s^{reco} - %s^{MC} (%s)", ptTitle.Data(), ptTitle.Data(), ptUnits.Data()));
496 histoIndex = GetHistoIndex(kHistoPtResolutionMC, itrig, isrc);
497 fHistoListMC->AddAt(histo1D, histoIndex);
502 if ( fFillTreeScaleDown > 0 ) {
503 TString leavesFloat[kNvarFloat] = {"Px", "Py", "Pz", "Pt",
504 "PxAtDCA", "PyAtDCA", "PzAtDCA", "PtAtDCA",
505 "PxUncorrected", "PyUncorrected", "PzUncorrected", "PtUncorrected",
506 "XUncorrected", "YUncorrected", "ZUncorrected",
507 "XatDCA", "YatDCA", "DCA",
508 "Eta", "Rapidity", "Charge", "RAtAbsEnd",
509 "IPVx", "IPVy", "IPVz", "Centrality"};
510 TString leavesInt[kNvarInt] = {"MatchTrig", "IsMuon", "IsGhost", "LoCircuit", "PassPhysicsSelection", "NVtxContrib", "NspdTracklets", "IsPileupVertex"};
511 TString leavesChar[kNvarChar] = {"FiredTrigClass"};
512 TString leavesUInt[kNvarUInt] = {"BunchCrossNum", "OrbitNum", "PeriodNum", "RunNum"};
513 TString leavesFloatMC[kNvarFloatMC] = {"PxMC", "PyMC", "PzMC", "PtMC",
514 "EtaMC", "RapidityMC",
515 "VxMC", "VyMC", "VzMC",
516 "MotherPxMC", "MotherPyMC", "MotherPzMC",
517 "MotherEtaMC", "MotherRapidityMC",
518 "MotherVxMC", "MotherVyMC", "MotherVzMC",
519 "IPVxMC", "IPVyMC", "IPVzMC"};
520 TString leavesIntMC[kNvarIntMC] = {"Pdg", "MotherPdg", "MotherType"};
522 TString treeName = GetOutputSlot(5)->GetContainer()->GetName();
523 Bool_t hasMC = AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler();
524 TString treeTitle = ( hasMC ) ? "Single Mu" : "Single Mu MC";
527 if ( ! fTreeSingleMu ) fTreeSingleMu = new TTree(treeName.Data(), treeTitle.Data());
529 for(Int_t itree=0; itree<2; itree++){
530 TParameter<Int_t>* par1 = new TParameter<Int_t>("fillTreeScaleDown",fFillTreeScaleDown);
531 TParameter<Int_t>* par2 = new TParameter<Int_t>("keepAllEvents",fKeepAll);
532 fTreeSingleMu->GetUserInfo()->Add(par1);
533 fTreeSingleMu->GetUserInfo()->Add(par2);
534 for(Int_t ivar=0; ivar<kNvarFloat; ivar++){
535 fTreeSingleMu->Branch(leavesFloat[ivar].Data(), &fVarFloat[ivar], Form("%s/F", leavesFloat[ivar].Data()));
537 for(Int_t ivar=0; ivar<kNvarInt; ivar++){
538 fTreeSingleMu->Branch(leavesInt[ivar].Data(), &fVarInt[ivar], Form("%s/I", leavesInt[ivar].Data()));
540 for(Int_t ivar=0; ivar<kNvarChar; ivar++){
541 TString addString = leavesChar[ivar] + "/C";
542 fTreeSingleMu->Branch(leavesChar[ivar].Data(), fVarChar[ivar], addString.Data());
544 for(Int_t ivar=0; ivar<kNvarUInt; ivar++){
545 fTreeSingleMu->Branch(leavesUInt[ivar].Data(), &fVarUInt[ivar], Form("%s/i", leavesUInt[ivar].Data()));
548 for(Int_t ivar=0; ivar<kNvarFloatMC; ivar++){
549 fTreeSingleMu->Branch(leavesFloatMC[ivar].Data(), &fVarFloatMC[ivar], Form("%s/F", leavesFloatMC[ivar].Data()));
551 for(Int_t ivar=0; ivar<kNvarIntMC; ivar++){
552 fTreeSingleMu->Branch(leavesIntMC[ivar].Data(), &fVarIntMC[ivar], Form("%s/I", leavesIntMC[ivar].Data()));
556 PostData(5, fTreeSingleMu);
559 PostData(1, fCFManager->GetParticleContainer());
560 PostData(2, fHistoList);
561 PostData(3, fHistoListQA);
562 PostData(4, fHistoListMC);
566 //________________________________________________________________________
567 void AliAnalysisTaskSingleMu::UserExec(Option_t * /*option*/)
571 /// Called for each event
574 AliESDEvent* esdEvent = 0x0;
575 AliAODEvent* aodEvent = 0x0;
577 esdEvent = dynamic_cast<AliESDEvent*> (InputEvent());
579 aodEvent = dynamic_cast<AliAODEvent*> (InputEvent());
582 if ( ! aodEvent && ! esdEvent ) {
583 AliError ("AOD or ESD event not found. Nothing done!");
587 if ( ! fMCEvent && InputEvent()->GetEventType() != 7 ) return; // Run only on physics events!
589 Bool_t fillCurrentEventTree = ( fFillTreeScaleDown == 0 ) ? kFALSE : ( Entry() % fFillTreeScaleDown == 0 );
596 TString firedTrigClasses = ( esdEvent ) ? esdEvent->GetFiredTriggerClasses() : aodEvent->GetFiredTriggerClasses();
597 fVarFloat[kVarCentrality] = InputEvent()->GetCentrality()->GetCentralityPercentile("V0M");
599 AliVVertex* primaryVertex = ( esdEvent ) ? (AliVVertex*)esdEvent->GetPrimaryVertexSPD() : (AliVVertex*)aodEvent->GetPrimaryVertexSPD();
601 fVarFloat[kVarIPVz] = primaryVertex->GetZ();
602 fVarInt[kVarNVtxContrib] = primaryVertex->GetNContributors();
603 fVarInt[kVarIsPileup] = ( esdEvent ) ? esdEvent->IsPileupFromSPDInMultBins() : aodEvent->IsPileupFromSPDInMultBins();
604 fVarUInt[kVarRunNumber] = InputEvent()->GetRunNumber();
606 Int_t isGoodVtxBin = ( fVarInt[kVarNVtxContrib] >= fkNvtxContribCut );
607 if ( isGoodVtxBin && fVarInt[kVarIsPileup] > 0 )
610 if ( fillCurrentEventTree ){
611 strncpy(fVarChar[kVarTrigMask], firedTrigClasses.Data(),255);
612 fVarInt[kVarPassPhysicsSelection] = fInputHandler->IsEventSelected();
614 // Small workaround: in MC the bunch ID are not properly set and the timestamp is in seconds
615 // So fill bunchCrossing with the read timestamp
616 // fill the orbit and period number with a timestamp created while reading the run
618 fVarUInt[kVarBunchCrossNumber] = ( fMCEvent ) ? (UInt_t)Entry() : InputEvent()->GetBunchCrossNumber();
619 fVarUInt[kVarOrbitNumber] = ( fMCEvent ) ? (UInt_t)ts.GetNanoSec() : InputEvent()->GetOrbitNumber();
620 fVarUInt[kVarPeriodNumber] = ( fMCEvent ) ? ts.GetTime() : InputEvent()->GetPeriodNumber();
622 fVarFloat[kVarIPVx] = primaryVertex->GetX();
623 fVarFloat[kVarIPVy] = primaryVertex->GetY();
625 fVarInt[kVarNspdTracklets] = esdEvent->GetMultiplicity()->GetNumberOfTracklets();
626 else if ( aodEvent->GetTracklets() )
627 fVarInt[kVarNspdTracklets] = aodEvent->GetTracklets()->GetNumberOfTracklets();
630 firedTrigClasses.Append(" ANY");
632 // Object declaration
633 AliMCParticle* mcPart = 0x0;
634 AliVParticle* track = 0x0;
636 Double_t containerInput[kNvars];
637 Int_t histoIndex = -1;
639 fCFManager->SetRecEventInfo(InputEvent());
642 // Pure Monte Carlo part
645 fCFManager->SetMCEventInfo (fMCEvent);
646 Int_t nMCtracks = fMCEvent->GetNumberOfTracks();
647 if ( nMCtracks > 0 ) {
648 fVarFloatMC[kVarIPVxMC] = fMCEvent->Stack()->Particle(0)->Vx();
649 fVarFloatMC[kVarIPVyMC] = fMCEvent->Stack()->Particle(0)->Vy();
650 fVarFloatMC[kVarIPVzMC] = fMCEvent->Stack()->Particle(0)->Vz();
651 containerInput[kHvarVz] = fVarFloatMC[kVarIPVzMC];
652 containerInput[kHvarIsGoodVtx] = 1;
653 containerInput[kHvarCentrality] = fVarFloat[kVarCentrality];
654 histoIndex = GetHistoIndex(kHistoCheckVzMC);
655 ((TH2F*)fHistoListMC->At(histoIndex))->Fill(fVarFloat[kVarIPVz], fVarFloatMC[kVarIPVzMC]);
656 if ( isGoodVtxBin >= 1 ) {
657 histoIndex = GetHistoIndex(kHistoCheckVzHasVtxMC);
658 ((TH2F*)fHistoListMC->At(histoIndex))->Fill(fVarFloat[kVarIPVz], fVarFloatMC[kVarIPVzMC]);
660 if ( isGoodVtxBin == 1 ) {
661 histoIndex = GetHistoIndex(kHistoCheckVzNoPileupMC);
662 ((TH2F*)fHistoListMC->At(histoIndex))->Fill(fVarFloat[kVarIPVz], fVarFloatMC[kVarIPVzMC]);
666 for (Int_t ipart=0; ipart<nMCtracks; ipart++) {
667 mcPart = (AliMCParticle*)fMCEvent->GetTrack(ipart);
669 //check the MC-level cuts
670 if ( ! fCFManager->CheckParticleCuts(kStepGeneratedMC,mcPart) )
673 containerInput[kHvarPt] = mcPart->Pt();
674 //containerInput[kHvarY] = mcPart->Y();
675 containerInput[kHvarEta] = mcPart->Eta();
676 containerInput[kHvarPhi] = mcPart->Phi();
677 containerInput[kHvarDCA] = TMath::Sqrt(mcPart->Xv()*mcPart->Xv() +
678 mcPart->Yv()*mcPart->Yv());
679 containerInput[kHvarThetaZones] = GetBinThetaAbsEnd(TMath::Pi()-mcPart->Theta(),kTRUE);
680 containerInput[kHvarCharge] = mcPart->Charge()/3.;
681 containerInput[kHvarMatchTrig] = 1.;
682 containerInput[kHvarMotherType] = (Double_t)RecoTrackMother(mcPart);
683 //containerInput[kHvarP] = mcPart->P();
685 for ( Int_t itrig=0; itrig<fTriggerClasses->GetEntries(); itrig++ ) {
686 TString trigName = ((TObjString*)fTriggerClasses->At(itrig))->GetString();
687 if ( ! firedTrigClasses.Contains(trigName.Data()) )
689 containerInput[kHvarTrigClass] = (Double_t)(itrig+1);
690 fCFManager->GetParticleContainer()->Fill(containerInput,kStepGeneratedMC);
691 // if ( fCFManager->CheckParticleCuts(kStepAcceptanceMC,mcPart) ) fCFManager->GetParticleContainer()->Fill(containerInput,kStepAcceptanceMC);
692 } // loop on trigger classes
693 if ( fDebug >= 2 ) printf("AliAnalysisTaskSingleMu: Pure MC. %s. Set mother %i\n", fDebugString.Data(), (Int_t)containerInput[kHvarMotherType]);
694 } // loop on MC particles
699 // Reconstruction part
701 Int_t trackLabel = -1;
702 Bool_t isGhost = kFALSE;
703 Int_t nGhosts = 0, nMuons = 0;
705 Int_t nTracks = ( esdEvent ) ? esdEvent->GetNumberOfMuonTracks() : aodEvent->GetNTracks();
707 for (Int_t itrack = 0; itrack < nTracks; itrack++) {
709 track = esdEvent->GetMuonTrack(itrack);
710 isGhost = ( ((AliESDMuonTrack*)track)->ContainTriggerData() && ! ((AliESDMuonTrack*)track)->ContainTrackerData() );
713 track = aodEvent->GetTrack(itrack);
714 if ( ! ((AliAODTrack*)track)->IsMuonTrack() )
720 // Nothing to do for ghosts if the tree is not filled
721 if ( ! fillCurrentEventTree ) continue;
725 fVarFloat[kVarPt] = track->Pt();
726 //fVarFloat[kVarRapidity] = ( isGhost ) ? 0. : track->Y();
727 fVarFloat[kVarEta] = ( isGhost ) ? 0. : track->Eta();
728 fVarFloat[kVarXatDCA] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->GetNonBendingCoorAtDCA() : ((AliAODTrack*)track)->XAtDCA();
729 fVarFloat[kVarYatDCA] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->GetBendingCoorAtDCA() : ((AliAODTrack*)track)->YAtDCA();
731 TMath::Sqrt( fVarFloat[kVarXatDCA] * fVarFloat[kVarXatDCA] +
732 fVarFloat[kVarYatDCA] * fVarFloat[kVarYatDCA] );
733 fVarFloat[kVarCharge] = ( isGhost ) ? 0. : (Float_t)track->Charge();
734 fVarFloat[kVarRAtAbsEnd] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->GetRAtAbsorberEnd() : ((AliAODTrack*)track)->GetRAtAbsorberEnd();
735 fVarInt[kVarMatchTrig] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->GetMatchTrigger() : ((AliAODTrack*)track)->GetMatchTrigger();
737 fVarIntMC[kVarMotherType] = kUnknownPart;
741 trackLabel = track->GetLabel();
742 if ( trackLabel >= 0 ) {
743 AliMCParticle* matchedMCTrack = (AliMCParticle*)fMCEvent->GetTrack(trackLabel);
744 fVarIntMC[kVarMotherType] = RecoTrackMother(matchedMCTrack);
745 fVarFloatMC[kVarPtMC] = matchedMCTrack->Pt();
746 if ( ! isGhost ) FillTriggerHistos(kHistoPtResolutionMC, fVarInt[kVarMatchTrig], fVarIntMC[kVarMotherType], fVarFloat[kVarPt] - fVarFloatMC[kVarPtMC]);
747 if ( fillCurrentEventTree ){
748 fVarFloatMC[kVarPxMC] = matchedMCTrack->Px();
749 fVarFloatMC[kVarPyMC] = matchedMCTrack->Py();
750 fVarFloatMC[kVarPzMC] = matchedMCTrack->Pz();
751 fVarFloatMC[kVarEtaMC] = matchedMCTrack->Eta();
752 fVarFloatMC[kVarRapidityMC] = matchedMCTrack->Y();
753 fVarFloatMC[kVarVxMC] = matchedMCTrack->Xv();
754 fVarFloatMC[kVarVyMC] = matchedMCTrack->Yv();
755 fVarFloatMC[kVarVzMC] = matchedMCTrack->Zv();
756 fVarIntMC[kVarPdg] = matchedMCTrack->PdgCode();
758 Int_t imother = matchedMCTrack->GetMother();
759 if ( imother >= 0 ) {
760 AliMCParticle* motherTrack = (AliMCParticle*)fMCEvent->GetTrack(imother);
761 fVarFloatMC[kVarMotherPxMC] = motherTrack->Px();
762 fVarFloatMC[kVarMotherPyMC] = motherTrack->Py();
763 fVarFloatMC[kVarMotherPzMC] = motherTrack->Pz();
764 fVarFloatMC[kVarMotherEtaMC] = motherTrack->Eta();
765 fVarFloatMC[kVarMotherRapidityMC] = motherTrack->Y();
766 fVarFloatMC[kVarMotherVxMC] = motherTrack->Xv();
767 fVarFloatMC[kVarMotherVyMC] = motherTrack->Yv();
768 fVarFloatMC[kVarMotherVzMC] = motherTrack->Zv();
769 fVarIntMC[kVarMotherPdg] = motherTrack->PdgCode();
773 if ( fDebug >= 1 ) printf("AliAnalysisTaskSingleMu: Reco track. %s. Set mother %i\n", fDebugString.Data(), fVarIntMC[kVarMotherType]);
776 if ( fillCurrentEventTree ) {
777 fVarInt[kVarIsMuon] = ( isGhost ) ? 0 : nMuons;
778 fVarInt[kVarIsGhost] = ( isGhost ) ? nGhosts : 0;
779 //fVarFloat[kVarEta] = ( isGhost ) ? 0. : track->Eta();
780 fVarFloat[kVarRapidity] = ( isGhost ) ? 0.: track->Y();
781 fVarFloat[kVarPx] = track->Px();
782 fVarFloat[kVarPy] = track->Py();
783 fVarFloat[kVarPz] = track->Pz();
784 fVarFloat[kVarPxAtDCA] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->PxAtDCA() : ((AliAODTrack*)track)->PxAtDCA();
785 fVarFloat[kVarPyAtDCA] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->PyAtDCA() : ((AliAODTrack*)track)->PyAtDCA();
786 fVarFloat[kVarPzAtDCA] = ( esdEvent ) ? ((AliESDMuonTrack*)track)->PzAtDCA() : ((AliAODTrack*)track)->PzAtDCA();
787 fVarFloat[kVarPtAtDCA] = TMath::Sqrt(fVarFloat[kVarPxAtDCA]*fVarFloat[kVarPxAtDCA] + fVarFloat[kVarPyAtDCA]*fVarFloat[kVarPyAtDCA]);
789 // Information present only on ESD tracks
791 fVarFloat[kVarPxUncorrected] = ( isGhost ) ? -TMath::Tan(((AliESDMuonTrack*)track)->GetThetaXUncorrected()) : ((AliESDMuonTrack*)track)->PxUncorrected();
792 fVarFloat[kVarPyUncorrected] = ( isGhost ) ? -TMath::Tan(((AliESDMuonTrack*)track)->GetThetaYUncorrected()) : ((AliESDMuonTrack*)track)->PyUncorrected();
793 fVarFloat[kVarPzUncorrected] = ( isGhost ) ? -1 : ((AliESDMuonTrack*)track)->PzUncorrected();
795 fVarFloat[kVarPtUncorrected] =
796 TMath::Sqrt(fVarFloat[kVarPxUncorrected] * fVarFloat[kVarPxUncorrected] +
797 fVarFloat[kVarPyUncorrected] * fVarFloat[kVarPyUncorrected]);
799 fVarFloat[kVarXUncorrected] = ((AliESDMuonTrack*)track)->GetNonBendingCoorUncorrected();
800 fVarFloat[kVarYUncorrected] = ((AliESDMuonTrack*)track)->GetBendingCoorUncorrected();
801 fVarFloat[kVarZUncorrected] = ((AliESDMuonTrack*)track)->GetZUncorrected();
803 fVarInt[kVarLocalCircuit] = ((AliESDMuonTrack*)track)->LoCircuit();
806 fTreeSingleMu->Fill();
809 if ( isGhost ) continue;
814 containerInput[kHvarPt] = fVarFloat[kVarPt];
815 //containerInput[kHvarY] = fVarFloat[kVarRapidity];
816 containerInput[kHvarEta] = fVarFloat[kVarEta];
817 containerInput[kHvarPhi] = track->Phi();
818 containerInput[kHvarDCA] = fVarFloat[kVarDCA];
819 containerInput[kHvarVz] = fVarFloat[kVarIPVz];
820 containerInput[kHvarThetaZones] = GetBinThetaAbsEnd(fVarFloat[kVarRAtAbsEnd]);
821 containerInput[kHvarCharge] = fVarFloat[kVarCharge];
822 containerInput[kHvarMatchTrig] = (Double_t)fVarInt[kVarMatchTrig];
823 containerInput[kHvarIsGoodVtx] = (Double_t)isGoodVtxBin;
824 containerInput[kHvarMotherType] = (Double_t)fVarIntMC[kVarMotherType];
825 containerInput[kHvarCentrality] = fVarFloat[kVarCentrality];
826 //containerInput[kHvarP] = track->P();
828 histoIndex = GetHistoIndex(kHistoNmuonsPerRun);
829 for ( Int_t itrig=0; itrig<fTriggerClasses->GetEntries(); itrig++ ) {
830 TString trigName = ((TObjString*)fTriggerClasses->At(itrig))->GetString();
831 if ( ! firedTrigClasses.Contains(trigName.Data()) )
833 containerInput[kHvarTrigClass] = (Double_t)(itrig+1);
834 fCFManager->GetParticleContainer()->Fill(containerInput,kStepReconstructed);
835 // if ( fCFManager->CheckParticleCuts(kStepAcceptance,track) ) fCFManager->GetParticleContainer()->Fill(containerInput,kStepAcceptance);
836 ((TH2F*)fHistoList->At(histoIndex))->Fill(Form("%u",fVarUInt[kVarRunNumber]), containerInput[kHvarTrigClass], 1.);
837 } // loop on trigger classes
841 // Complete global information
843 if ( fillCurrentEventTree && fKeepAll && ( ( nMuons + nGhosts ) == 0 ) ) {
844 // Fill event also if there is not muon (when explicitely required)
845 fTreeSingleMu->Fill();
848 for ( Int_t itrig=0; itrig<fTriggerClasses->GetEntries(); itrig++ ) {
849 TString trigName = ((TObjString*)fTriggerClasses->At(itrig))->GetString();
850 if ( ! firedTrigClasses.Contains(trigName.Data()) )
852 Double_t trigClassBin = (Double_t)(itrig+1);
853 histoIndex = GetHistoIndex(kHistoNeventsPerTrig);
854 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 1., 1.); // All events
855 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 4., (Double_t)(fVarInt[kVarIsPileup]+1)); // All vertices
856 if ( isGoodVtxBin == 1 )
857 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 2., 1.); // Good vtx events
858 else if ( isGoodVtxBin == 2 ) {
859 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 3., 1.); // Pileup events
860 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin, 5., 1.); // Pileup vertices
863 histoIndex = GetHistoIndex(kHistoMuonMultiplicity);
864 ((TH1F*)fHistoList->At(histoIndex))->Fill(nMuons, trigClassBin);
866 if ( isGoodVtxBin == 1 ) {
867 histoIndex = GetHistoIndex(kHistoEventVz);
868 ((TH2F*)fHistoList->At(histoIndex))->Fill(trigClassBin,fVarFloat[kVarIPVz]);
871 histoIndex = GetHistoIndex(kHistoNeventsPerRun);
872 ((TH2F*)fHistoList->At(histoIndex))->Fill(Form("%u",fVarUInt[kVarRunNumber]), trigClassBin, 1.);
873 } // loop on trigger classes
876 // Post final data. It will be written to a file with option "RECREATE"
877 PostData(1, fCFManager->GetParticleContainer());
878 PostData(2, fHistoList);
879 PostData(3, fHistoListQA);
880 PostData(4, fHistoListMC);
881 if ( fFillTreeScaleDown > 0 )
882 PostData(5, fTreeSingleMu);
885 //________________________________________________________________________
886 void AliAnalysisTaskSingleMu::Terminate(Option_t *) {
888 /// Draw some histogram at the end.
891 AliCFContainer* container = dynamic_cast<AliCFContainer*> (GetOutputData(1));
893 AliError("Cannot find container in file");
897 //Int_t histoIndex = -1;
899 if ( ! gROOT->IsBatch() ) {
900 TString currName = GetName();
901 currName.Prepend("c1_");
902 TCanvas *c1_SingleMu = new TCanvas(currName.Data(),"Vz vs Pt",10,10,310,310);
903 c1_SingleMu->SetFillColor(10); c1_SingleMu->SetHighLightColor(10);
904 c1_SingleMu->SetLeftMargin(0.15); c1_SingleMu->SetBottomMargin(0.15);
905 TH2* histo = static_cast<TH2*>(container->Project(kStepReconstructed,kHvarPt,kHvarVz));
906 currName = GetName();
907 currName.Prepend("hPtVz_");
908 histo->SetName(currName.Data());
914 //________________________________________________________________________
915 void AliAnalysisTaskSingleMu::FillTriggerHistos(Int_t histoIndex, Int_t matchTrig, Int_t motherType,
916 Float_t var1, Float_t var2, Float_t var3)
919 /// Fill all histograms passing the trigger cuts
922 Int_t nTrigs = TMath::Max(1, matchTrig);
923 TArrayI trigToFill(nTrigs);
924 trigToFill[0] = matchTrig;
925 for(Int_t itrig = 1; itrig < matchTrig; itrig++){
926 trigToFill[itrig] = itrig;
929 TList* histoList = (motherType < 0 ) ? fHistoList : fHistoListMC;
932 for(Int_t itrig = 0; itrig < nTrigs; itrig++){
933 Int_t currIndex = GetHistoIndex(histoIndex, trigToFill[itrig], motherType);
934 className = histoList->At(currIndex)->ClassName();
935 if ( fDebug >= 3 ) printf("AliAnalysisTaskSingleMu: matchTrig %i Fill %s\n", matchTrig, histoList->At(currIndex)->GetName());
936 if (className.Contains("1"))
937 ((TH1F*)histoList->At(currIndex))->Fill(var1);
938 else if (className.Contains("2"))
939 ((TH2F*)histoList->At(currIndex))->Fill(var1, var2);
940 else if (className.Contains("3"))
941 ((TH3F*)histoList->At(currIndex))->Fill(var1, var2, var3);
943 AliWarning("Histogram not filled");
947 //________________________________________________________________________
948 Int_t AliAnalysisTaskSingleMu::RecoTrackMother(AliMCParticle* mcParticle)
951 /// Find track mother from kinematics
954 Int_t recoPdg = mcParticle->PdgCode();
956 fDebugString = Form("History: %i", recoPdg);
958 // Track is not a muon
959 if ( TMath::Abs(recoPdg) != 13 ) return kRecoHadron;
961 Int_t imother = mcParticle->GetMother();
963 //Int_t baseFlv[2] = {4,5};
964 //Int_t mType[2] = {kCharmMu, kBeautyMu};
965 Int_t den[3] = {100, 1000, 1};
967 //Bool_t isFirstMotherHF = kFALSE;
969 Int_t motherType = kPrimaryMu;
970 while ( imother >= 0 ) {
971 TParticle* part = ((AliMCParticle*)fMCEvent->GetTrack(imother))->Particle();
973 fDebugString += Form(" <- %s (%s)", part->GetName(), TMCProcessName[part->GetUniqueID()]);
975 Int_t absPdg = TMath::Abs(part->GetPdgCode());
978 if ( imother < fMCEvent->GetNumberOfPrimaries() ) {
980 // Hadronic processes are not possible for "primary" =>
981 // either is decay or HF
982 if ( absPdg > 100 && absPdg < 400 ) {
984 motherType = kPrimaryMu;
985 break; // particle loop
987 else if ( step == 1 || isFirstMotherHF ){
988 // Check if it is HF muon
989 // avoid the case when the HF was not the first mother
990 // (the mu is produced by a decain chain => decay mu)
991 Bool_t foundHF = kFALSE;
992 for ( Int_t idec=0; idec<3; idec++ ) {
993 for ( Int_t ihf=0; ihf<2; ihf++ ) {
994 if ( ( absPdg/den[idec] ) != baseFlv[ihf] ) continue;
995 motherType = mType[ihf];
1000 if ( step == 1 ) isFirstMotherHF = kTRUE;
1001 break; // break loop on pdg code
1002 // but continue the global loop to find higher mass HF
1004 } // loop on pdg codes
1006 motherType = kPrimaryMu;
1009 else if ( absPdg < 10 ) {
1010 // found HF quark: break particle loop
1013 } // potential HF code
1015 for ( Int_t idec=0; idec<3; idec++ ) {
1016 Int_t flv = absPdg/den[idec];
1017 if ( flv > 0 && flv < 4 ) return kPrimaryMu;
1018 else if ( flv == 0 || flv > 5 ) continue;
1020 motherType = ( flv == 4 ) ? kCharmMu : kBeautyMu;
1021 break; // break loop on pdg code
1022 // but continue the global loop to find higher mass HF
1024 } // loop on pdg code
1025 if ( absPdg < 10 ) break; // particle loop
1028 // If hadronic process => secondary
1029 if ( part->GetUniqueID() == kPHadronic ) {
1030 //motherType = kSecondaryMu;
1031 //break; // particle loop
1032 return kSecondaryMu;
1036 imother = part->GetFirstMother();
1038 } // loop on mothers
1043 //________________________________________________________________________
1044 Int_t AliAnalysisTaskSingleMu::GetHistoIndex(Int_t histoTypeIndex, Int_t trigIndex, Int_t srcIndex)
1047 /// Get histogram index in the list
1050 if ( srcIndex < 0 ) {
1051 return histoTypeIndex;
1056 kNtrackSources * kNtrigCuts * histoTypeIndex +
1057 kNtrackSources * trigIndex +
1061 //________________________________________________________________________
1062 Float_t AliAnalysisTaskSingleMu::GetBinThetaAbsEnd(Float_t RAtAbsEnd, Bool_t isTheta)
1065 /// Get bin of theta at absorber end region
1067 Float_t thetaDeg = ( isTheta ) ? RAtAbsEnd : TMath::ATan( RAtAbsEnd / 505. );
1068 thetaDeg *= TMath::RadToDeg();
1069 if ( thetaDeg < 2. )
1071 else if ( thetaDeg < 3. )
1073 else if ( thetaDeg < 9. )
1080 //________________________________________________________________________
1081 void AliAnalysisTaskSingleMu::Reset(Bool_t keepGlobal)
1086 Int_t lastVarFloat = ( keepGlobal ) ? kVarIPVx : kNvarFloat;
1087 for(Int_t ivar=0; ivar<lastVarFloat; ivar++){
1088 fVarFloat[ivar] = 0.;
1090 Int_t lastVarInt = ( keepGlobal ) ? kVarPassPhysicsSelection : kNvarInt;
1091 for(Int_t ivar=0; ivar<lastVarInt; ivar++){
1094 fVarInt[kVarMatchTrig] = -1;
1096 if ( ! keepGlobal ){
1097 for(Int_t ivar=0; ivar<kNvarChar; ivar++){
1098 strncpy(fVarChar[ivar]," ",255);
1100 for(Int_t ivar=0; ivar<kNvarUInt; ivar++){
1105 lastVarFloat = ( keepGlobal ) ? kVarIPVxMC : kNvarFloatMC;
1106 for(Int_t ivar=0; ivar<lastVarFloat; ivar++){
1107 fVarFloatMC[ivar] = 0.;
1109 for(Int_t ivar=0; ivar<kNvarIntMC; ivar++){
1110 fVarIntMC[ivar] = 0;
1112 fVarIntMC[kVarMotherType] = -1;
1116 //________________________________________________________________________
1117 void AliAnalysisTaskSingleMu::SetTriggerClasses(TString triggerClasses)
1119 /// Set trigger classes
1120 if ( fTriggerClasses )
1121 delete fTriggerClasses;
1123 fTriggerClasses = triggerClasses.Tokenize(" ");
1124 fTriggerClasses->SetOwner();
1128 //________________________________________________________________________
1129 void AliAnalysisTaskSingleMu::SetAxisLabel(TAxis* axis)
1132 /// Set the labels of trigger class axis
1134 for ( Int_t itrig=0; itrig<fTriggerClasses->GetEntries(); itrig++ ) {
1135 TString trigName = ((TObjString*)fTriggerClasses->At(itrig))->GetString();
1136 axis->SetBinLabel(itrig+1,trigName.Data());
1138 axis->SetTitle("Fired class");