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 **************************************************************************/
16 //-----------------------------------------------------------------------------
17 /// \class AliAnalysisTaskSingleMu
18 /// Analysis task for single muons in the spectrometer.
19 /// The output is a list of histograms.
20 /// The macro class can run on AODs or ESDs.
21 /// In the latter case a flag can be activated to produce a tree as output.
22 /// If Monte Carlo information is present, some basics checks are performed.
24 /// \author Diego Stocco
25 //-----------------------------------------------------------------------------
27 //----------------------------------------------------------------------------
28 // Implementation of the single muon analysis class
29 // An example of usage can be found in the macro RunSingleMuAnalysisFromAOD.C.
30 //----------------------------------------------------------------------------
32 #define AliAnalysisTaskSingleMu_cxx
44 #include "TTimeStamp.h"
49 #include "AliAODEvent.h"
50 #include "AliAODTrack.h"
51 #include "AliAODVertex.h"
53 #include "AliMCEvent.h"
54 #include "AliMCParticle.h"
57 #include "AliESDInputHandler.h"
58 #include "AliESDEvent.h"
59 #include "AliESDMuonTrack.h"
60 #include "AliAnalysisManager.h"
62 #include "AliAnalysisTaskSE.h"
63 #include "AliAnalysisTaskSingleMu.h"
66 ClassImp(AliAnalysisTaskSingleMu) // Class implementation in ROOT context
70 //________________________________________________________________________
71 AliAnalysisTaskSingleMu::AliAnalysisTaskSingleMu(const char *name, Bool_t fillTree, Bool_t keepAll) :
72 AliAnalysisTaskSE(name),
93 DefineOutput(1, TList::Class());
94 DefineOutput(2, TList::Class());
97 DefineOutput(3, TTree::Class());
101 //________________________________________________________________________
102 AliAnalysisTaskSingleMu::~AliAnalysisTaskSingleMu()
109 delete fTreeSingleMu;
110 delete fTreeSingleMuMC;
120 //___________________________________________________________________________
121 void AliAnalysisTaskSingleMu::NotifyRun()
124 /// Use the event handler information to correctly fill the analysis flags:
125 /// - check if Monte Carlo information is present
130 AliInfo("Monte Carlo information is present");
133 AliInfo("No Monte Carlo information in run");
138 //___________________________________________________________________________
139 void AliAnalysisTaskSingleMu::UserCreateOutputObjects()
142 /// Create output histograms
144 AliInfo(Form(" CreateOutputObjects of task %s\n", GetName()));
146 if ( fFillTree ) OpenFile(1);
148 // initialize histogram lists
149 if(!fHistoList) fHistoList = new TList();
150 if(!fHistoListMC) fHistoListMC = new TList();
153 fVarFloat = new Float_t [kNvarFloat];
154 fVarInt = new Int_t [kNvarInt];
155 fVarChar = new Char_t *[kNvarChar];
156 fVarUInt = new UInt_t [kNvarUInt];
157 fVarFloatMC = new Float_t [kNvarFloatMC];
158 fVarIntMC = new Int_t [kNvarIntMC];
161 Float_t ptMin = 0., ptMax = 30.;
162 TString ptName("Pt"), ptTitle("p_{t}"), ptUnits("GeV/c");
164 Int_t nDcaBins = 100;
165 Float_t dcaMin = 0., dcaMax = 200.;
166 TString dcaName("DCA"), dcaTitle("DCA"), dcaUnits("cm");
169 Float_t vzMin = -30, vzMax = 30;
170 TString vzName("Vz"), vzTitle("Vz"), vzUnits("cm");
173 Float_t etaMin = -4.5, etaMax = -2.;
174 TString etaName("Eta"), etaTitle("#eta"), etaUnits("a.u.");
176 Int_t nRapidityBins = 25;
177 Float_t rapidityMin = -4.5, rapidityMax = -2.;
178 TString rapidityName("Rapidity"), rapidityTitle("rapidity"), rapidityUnits("a.u.");
180 TString trigName[kNtrigCuts];
181 trigName[kNoMatchTrig] = "NoMatch";
182 trigName[kAllPtTrig] = "AllPt";
183 trigName[kLowPtTrig] = "LowPt";
184 trigName[kHighPtTrig] = "HighPt";
186 TString srcName[kNtrackSources];
187 srcName[kCharmMu] = "Charm";
188 srcName[kBeautyMu] = "Beauty";
189 srcName[kPrimaryMu] = "Decay";
190 srcName[kSecondaryMu] = "Secondary";
191 srcName[kRecoHadron] = "Hadrons";
192 srcName[kUnknownPart] = "Unknown";
196 TString histoName, histoTitle;
197 Int_t histoIndex = 0;
200 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
201 histoName = Form("%sDistrib%sTrig", ptName.Data(), trigName[itrig].Data());
202 histoTitle = Form("%s distribution. Trigger: %s", ptTitle.Data(), trigName[itrig].Data());
203 histo1D = new TH1F(histoName.Data(), histoTitle.Data(), nPtBins, ptMin, ptMax);
204 histo1D->GetXaxis()->SetTitle(Form("%s (%s)", ptTitle.Data(), ptUnits.Data()));
205 histoIndex = GetHistoIndex(kHistoPt, itrig);
206 fHistoList->AddAt(histo1D, histoIndex);
209 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
210 histoName = Form("%sDistrib%sTrig", dcaName.Data(), trigName[itrig].Data());
211 histoTitle = Form("%s distribution. Trigger: %s", dcaTitle.Data(), trigName[itrig].Data());
212 histo1D = new TH1F(histoName.Data(), histoTitle.Data(), nDcaBins, dcaMin, dcaMax);
213 histo1D->GetXaxis()->SetTitle(Form("%s (%s)", dcaTitle.Data(), dcaUnits.Data()));
214 histoIndex = GetHistoIndex(kHistoDCA, itrig);
215 fHistoList->AddAt(histo1D, histoIndex);
218 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
219 histoName = Form("%sDistrib%sTrig", vzName.Data(), trigName[itrig].Data());
220 histoTitle = Form("%s distribution. Trigger: %s", vzTitle.Data(), trigName[itrig].Data());
221 histo1D = new TH1F(histoName.Data(), histoTitle.Data(), nVzBins, vzMin, vzMax);
222 histo1D->GetXaxis()->SetTitle(Form("%s (%s)", vzTitle.Data(), vzUnits.Data()));
223 histoIndex = GetHistoIndex(kHistoVz, itrig);
224 fHistoList->AddAt(histo1D, histoIndex);
227 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
228 histoName = Form("%sDistrib%sTrig", etaName.Data(), trigName[itrig].Data());
229 histoTitle = Form("%s distribution. Trigger: %s", etaTitle.Data(), trigName[itrig].Data());
230 histo1D = new TH1F(histoName.Data(), histoTitle.Data(), nEtaBins, etaMin, etaMax);
231 histo1D->GetXaxis()->SetTitle(Form("%s (%s)", etaTitle.Data(), etaUnits.Data()));
232 histoIndex = GetHistoIndex(kHistoEta, itrig);
233 fHistoList->AddAt(histo1D, histoIndex);
236 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
237 histoName = Form("%sDistrib%sTrig", rapidityName.Data(), trigName[itrig].Data());
238 histoTitle = Form("%s distribution. Trigger: %s", rapidityTitle.Data(), trigName[itrig].Data());
239 histo1D = new TH1F(histoName.Data(), histoTitle.Data(), nRapidityBins, rapidityMin, rapidityMax);
240 histo1D->GetXaxis()->SetTitle(Form("%s (%s)", rapidityTitle.Data(), rapidityUnits.Data()));
241 histoIndex = GetHistoIndex(kHistoRapidity, itrig);
242 fHistoList->AddAt(histo1D, histoIndex);
246 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
247 histoName = Form("%s%sDistrib%sTrig", dcaName.Data(), ptName.Data(), trigName[itrig].Data());
248 histoTitle = Form("%s vs. %s distribution. Trigger: %s", dcaTitle.Data(), ptTitle.Data(), trigName[itrig].Data());
249 histo2D = new TH2F(histoName.Data(), histoTitle.Data(),
250 nPtBins, ptMin, ptMax,
251 nDcaBins, dcaMin, dcaMax);
252 histo2D->GetXaxis()->SetTitle(Form("%s (%s)", ptTitle.Data(), ptUnits.Data()));
253 histo2D->GetYaxis()->SetTitle(Form("%s (%s)", dcaTitle.Data(), dcaUnits.Data()));
254 histoIndex = GetHistoIndex(kHistoPtDCA, itrig);
255 fHistoList->AddAt(histo2D, histoIndex);
258 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
259 histoName = Form("%s%sDistrib%sTrig", vzName.Data(), ptName.Data(), trigName[itrig].Data());
260 histoTitle = Form("%s vs. %s distribution. Trigger: %s", vzTitle.Data(), ptTitle.Data(), trigName[itrig].Data());
261 histo2D = new TH2F(histoName.Data(), histoTitle.Data(),
262 nPtBins, ptMin, ptMax,
263 nVzBins, vzMin, vzMax);
264 histo2D->GetXaxis()->SetTitle(Form("%s (%s)", ptTitle.Data(), ptUnits.Data()));
265 histo2D->GetYaxis()->SetTitle(Form("%s (%s)", vzTitle.Data(), vzUnits.Data()));
266 histoIndex = GetHistoIndex(kHistoPtVz, itrig);
267 fHistoList->AddAt(histo2D, histoIndex);
270 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
271 histoName = Form("%s%sDistrib%sTrig", rapidityName.Data(), ptName.Data(), trigName[itrig].Data());
272 histoTitle = Form("%s vs. %s distribution. Trigger: %s", rapidityTitle.Data(), ptTitle.Data(), trigName[itrig].Data());
273 histo2D = new TH2F(histoName.Data(), histoTitle.Data(),
274 nPtBins, ptMin, ptMax,
275 nRapidityBins, rapidityMin, rapidityMax);
276 histo2D->GetXaxis()->SetTitle(Form("%s (%s)", ptTitle.Data(), ptUnits.Data()));
277 histo2D->GetYaxis()->SetTitle(Form("%s (%s)", rapidityTitle.Data(), rapidityUnits.Data()));
278 histoIndex = GetHistoIndex(kHistoPtRapidity, itrig);
279 fHistoList->AddAt(histo2D, histoIndex);
283 histoName = "histoMuonMultiplicity";
284 histoTitle = "Muon track multiplicity";
285 histo1D = new TH1F(histoName.Data(), histoTitle.Data(), 10, -0.5, 10-0.5);
286 //histo1D->GetXaxis()->SetBinLabel(1, "All events");
287 //histo1D->GetXaxis()->SetBinLabel(2, "Muon events");
288 histo1D->GetXaxis()->SetTitle("# of muons");
289 histoIndex = GetHistoIndex(kNhistoTypes, 0) + kHistoMuonMultiplicity;
290 fHistoList->AddAt(histo1D, histoIndex);
293 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
294 for (Int_t isrc = 0; isrc < kNtrackSources; isrc++) {
295 histoName = Form("%sResolution%sTrig%s", ptName.Data(), trigName[itrig].Data(), srcName[isrc].Data());
296 histoTitle = Form("%s resolution. Trigger: %s (%s)", ptTitle.Data(), trigName[itrig].Data(), srcName[isrc].Data());
297 histo1D = new TH1F(histoName.Data(), histoTitle.Data(), 100, -5., 5.);
298 histo1D->GetXaxis()->SetTitle(Form("%s^{reco} - %s^{MC} (%s)", ptTitle.Data(), ptTitle.Data(), ptUnits.Data()));
299 histoIndex = GetHistoIndex(kHistoPtResolutionMC, itrig, isrc);
300 fHistoListMC->AddAt(histo1D, histoIndex);
304 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
305 for (Int_t isrc = 0; isrc < kNtrackSources; isrc++) {
306 histoName = Form("%s%sDistrib%sTrig%s", dcaName.Data(), ptName.Data(),
307 trigName[itrig].Data(), srcName[isrc].Data());
308 histoTitle = Form("%s vs. %s distribution. Trigger: %s (%s)", dcaTitle.Data(), ptTitle.Data(),
309 trigName[itrig].Data(), srcName[isrc].Data());
310 histo2D = new TH2F(histoName.Data(), histoTitle.Data(),
311 nPtBins, ptMin, ptMax,
312 nDcaBins, dcaMin, dcaMax);
313 histo2D->GetXaxis()->SetTitle(Form("%s (%s)", ptTitle.Data(), ptUnits.Data()));
314 histo2D->GetYaxis()->SetTitle(Form("%s (%s)", dcaTitle.Data(), dcaUnits.Data()));
315 histoIndex = GetHistoIndex(kHistoPtDCAMC, itrig, isrc);
316 fHistoListMC->AddAt(histo2D, histoIndex);
320 for (Int_t itrig=0; itrig < kNtrigCuts; itrig++) {
321 for (Int_t isrc = 0; isrc < kNtrackSources; isrc++) {
322 histoName = Form("%s%sDistrib%sTrig%s", vzName.Data(), ptName.Data(),
323 trigName[itrig].Data(), srcName[isrc].Data());
324 histoTitle = Form("%s vs. %s distribution. Trigger: %s (%s)", vzTitle.Data(), ptTitle.Data(),
325 trigName[itrig].Data(), srcName[isrc].Data());
326 histo2D = new TH2F(histoName.Data(), histoTitle.Data(),
327 nPtBins, ptMin, ptMax,
328 nVzBins, vzMin, vzMax);
329 histo2D->GetXaxis()->SetTitle(Form("%s (%s)", ptTitle.Data(), ptUnits.Data()));
330 histo2D->GetYaxis()->SetTitle(Form("%s (%s)", vzTitle.Data(), vzUnits.Data()));
331 histoIndex = GetHistoIndex(kHistoPtVzMC, itrig, isrc);
332 fHistoListMC->AddAt(histo2D, histoIndex);
338 TString leavesFloat[kNvarFloat] = {"Px", "Py", "Pz", "Pt",
339 "PxAtDCA", "PyAtDCA", "PzAtDCA", "PtAtDCA",
340 "PxUncorrected", "PyUncorrected", "PzUncorrected", "PtUncorrected",
341 "XUncorrected", "YUncorrected", "ZUncorrected",
342 "XatDCA", "YatDCA", "DCA",
343 "Eta", "Rapidity", "Charge",
344 "IPVx", "IPVy", "IPVz"};
345 TString leavesInt[kNvarInt] = {"MatchTrig", "IsMuon", "IsGhost", "PassPhysicsSelection"};
346 TString leavesChar[kNvarChar] = {"FiredTrigClass"};
347 const Int_t charWidth[kNvarChar] = {255};
348 TString leavesUInt[kNvarUInt] = {"BunchCrossNum", "OrbitNum", "PeriodNum", "RunNum"};
349 TString leavesFloatMC[kNvarFloatMC] = {"PxMC", "PyMC", "PzMC", "PtMC", "EtaMC", "RapidityMC", "VxMC", "VyMC", "VzMC"};
350 TString leavesIntMC[kNvarIntMC] = {"Pdg", "MotherType"};
352 if ( ! fTreeSingleMu ) fTreeSingleMu = new TTree("fTreeSingleMu", "Single Mu");
353 if ( ! fTreeSingleMuMC ) fTreeSingleMuMC = new TTree("fTreeSingleMuMC", "Single Mu MC");
355 TTree* currTree[2] = {fTreeSingleMu, fTreeSingleMuMC};
356 //TList* currList[2] = {fHistoList, fHistoListMC};
358 for(Int_t itree=0; itree<2; itree++){
359 for(Int_t ivar=0; ivar<kNvarFloat; ivar++){
360 currTree[itree]->Branch(leavesFloat[ivar].Data(), &fVarFloat[ivar], Form("%s/F", leavesFloat[ivar].Data()));
362 for(Int_t ivar=0; ivar<kNvarInt; ivar++){
363 currTree[itree]->Branch(leavesInt[ivar].Data(), &fVarInt[ivar], Form("%s/I", leavesInt[ivar].Data()));
365 for(Int_t ivar=0; ivar<kNvarChar; ivar++){
367 fVarChar[ivar] = new Char_t [charWidth[ivar]];
369 TString addString = leavesChar[ivar] + "/C";
370 currTree[itree]->Branch(leavesChar[ivar].Data(), fVarChar[ivar], addString.Data());
372 for(Int_t ivar=0; ivar<kNvarUInt; ivar++){
373 currTree[itree]->Branch(leavesUInt[ivar].Data(), &fVarUInt[ivar], Form("%s/i", leavesUInt[ivar].Data()));
376 for(Int_t ivar=0; ivar<kNvarFloatMC; ivar++){
377 currTree[itree]->Branch(leavesFloatMC[ivar].Data(), &fVarFloatMC[ivar], Form("%s/F", leavesFloatMC[ivar].Data()));
379 for(Int_t ivar=0; ivar<kNvarIntMC; ivar++){
380 currTree[itree]->Branch(leavesIntMC[ivar].Data(), &fVarIntMC[ivar], Form("%s/I", leavesIntMC[ivar].Data()));
387 //________________________________________________________________________
388 void AliAnalysisTaskSingleMu::UserExec(Option_t * /*option*/)
392 /// Called for each event
395 AliESDEvent* esdEvent = 0x0;
396 AliAODEvent* aodEvent = 0x0;
397 AliMCEvent* mcEvent = 0x0;
399 esdEvent = dynamic_cast<AliESDEvent*> (InputEvent());
402 aodEvent = dynamic_cast<AliAODEvent*> (InputEvent());
405 //aodEvent = AODEvent();
407 if ( ! aodEvent && ! esdEvent ) {
408 AliError ("AOD or ESD event not found. Nothing done!");
412 if ( ! fUseMC && InputEvent()->GetEventType() !=7 ) return; // Run only on physics events!
416 fVarInt[kVarPassPhysicsSelection] = ((AliESDInputHandler*)AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler())->IsEventSelected();
417 strcpy(fVarChar[kVarTrigMask], esdEvent->GetFiredTriggerClasses().Data());
419 // Small workaround: in MC the bunch ID are not properly set and the timestamp is in seconds
420 // So fill bunchCrossing with the read timestamp
421 // fill the orbit and period number with a timestamp created while reading the run
423 fVarUInt[kVarBunchCrossNumber] = ( fUseMC ) ? (UInt_t)Entry() : esdEvent->GetBunchCrossNumber();
424 fVarUInt[kVarOrbitNumber] = ( fUseMC ) ? ts.GetNanoSec() : esdEvent->GetOrbitNumber();
425 fVarUInt[kVarPeriodNumber] = ( fUseMC ) ? ts.GetTime() : esdEvent->GetPeriodNumber();
426 fVarUInt[kVarRunNumber] = esdEvent->GetRunNumber();
428 fVarFloat[kVarIPVx] = esdEvent->GetPrimaryVertex()->GetX();
429 fVarFloat[kVarIPVy] = esdEvent->GetPrimaryVertex()->GetY();
430 fVarFloat[kVarIPVz] = esdEvent->GetPrimaryVertex()->GetZ();
433 if ( fUseMC ) mcEvent = MCEvent();
435 // Object declaration
436 AliMCParticle* mcTrack = 0x0;
438 Int_t trackLabel = -1;
440 Int_t nTracks = ( esdEvent ) ? esdEvent->GetNumberOfMuonTracks() : aodEvent->GetNTracks();
442 Bool_t isGhost = kFALSE;
443 Int_t nGhosts = 0, nMuons = 0;
445 AliVParticle* track = 0x0;
447 for (Int_t itrack = 0; itrack < nTracks; itrack++) {
451 if (itrack>0) Reset(kTRUE);
453 track = esdEvent->GetMuonTrack(itrack);
454 isGhost = ( ((AliESDMuonTrack*)track)->ContainTriggerData() && ! ((AliESDMuonTrack*)track)->ContainTrackerData() );
457 fVarFloat[kVarPxUncorrected] = ( isGhost ) ? -TMath::Tan(((AliESDMuonTrack*)track)->GetThetaXUncorrected()) : ((AliESDMuonTrack*)track)->PxUncorrected();
458 fVarFloat[kVarPyUncorrected] = ( isGhost ) ? -TMath::Tan(((AliESDMuonTrack*)track)->GetThetaYUncorrected()) : ((AliESDMuonTrack*)track)->PyUncorrected();
459 fVarFloat[kVarPzUncorrected] = ( isGhost ) ? -1 : ((AliESDMuonTrack*)track)->PzUncorrected();
460 fVarFloat[kVarPtUncorrected] = TMath::Sqrt(
461 fVarFloat[kVarPxUncorrected] * fVarFloat[kVarPxUncorrected] +
462 fVarFloat[kVarPyUncorrected] * fVarFloat[kVarPyUncorrected]);
464 fVarFloat[kVarXUncorrected] = ((AliESDMuonTrack*)track)->GetNonBendingCoorUncorrected();
465 fVarFloat[kVarYUncorrected] = ((AliESDMuonTrack*)track)->GetBendingCoorUncorrected();
466 fVarFloat[kVarZUncorrected] = ((AliESDMuonTrack*)track)->GetZUncorrected();
468 fVarInt[kVarMatchTrig] = ((AliESDMuonTrack*)track)->GetMatchTrigger();
470 // If is ghost fill only a partial information
472 fVarInt[kVarIsMuon] = 0;
474 fVarInt[kVarIsGhost] = nGhosts;
476 if ( ! fUseMC ) fTreeSingleMu->Fill();
477 else fTreeSingleMuMC->Fill();
483 track = aodEvent->GetTrack(itrack);
484 if ( ! ((AliAODTrack*)track)->IsMuonTrack() )
490 // Information for tracks in tracker
492 fVarInt[kVarIsMuon] = nMuons;
493 fVarInt[kVarIsGhost] = 0;
495 fVarFloat[kVarPt] = track->Pt();
496 fVarFloat[kVarXatDCA] = (esdEvent ) ? ((AliESDMuonTrack*)track)->GetNonBendingCoorAtDCA() : ((AliAODTrack*)track)->XAtDCA();
497 fVarFloat[kVarYatDCA] = (esdEvent ) ? ((AliESDMuonTrack*)track)->GetBendingCoorAtDCA() : ((AliAODTrack*)track)->YAtDCA();
498 fVarFloat[kVarDCA] = TMath::Sqrt( fVarFloat[kVarXatDCA] * fVarFloat[kVarXatDCA] + fVarFloat[kVarYatDCA] * fVarFloat[kVarYatDCA] );
499 fVarFloat[kVarEta] = track->Eta();
500 fVarFloat[kVarRapidity] = track->Y();
501 trackLabel = track->GetLabel();
502 fVarInt[kVarMatchTrig] = (esdEvent ) ? ((AliESDMuonTrack*)track)->GetMatchTrigger() : ((AliAODTrack*)track)->GetMatchTrigger();
505 FillTriggerHistos(kHistoPt, fVarInt[kVarMatchTrig], -1, fVarFloat[kVarPt]);
506 FillTriggerHistos(kHistoDCA, fVarInt[kVarMatchTrig], -1, fVarFloat[kVarDCA]);
507 FillTriggerHistos(kHistoVz, fVarInt[kVarMatchTrig], -1, fVarFloat[kVarIPVz]);
508 FillTriggerHistos(kHistoEta, fVarInt[kVarMatchTrig], -1, fVarFloat[kVarEta]);
509 FillTriggerHistos(kHistoRapidity, fVarInt[kVarMatchTrig], -1, fVarFloat[kVarRapidity]);
511 FillTriggerHistos(kHistoPtDCA, fVarInt[kVarMatchTrig], -1, fVarFloat[kVarPt], fVarFloat[kVarDCA]);
512 FillTriggerHistos(kHistoPtVz, fVarInt[kVarMatchTrig], -1, fVarFloat[kVarPt], fVarFloat[kVarIPVz]);
513 FillTriggerHistos(kHistoPtRapidity, fVarInt[kVarMatchTrig], -1, fVarFloat[kVarPt], fVarFloat[kVarRapidity]);
516 fVarFloat[kVarPx] = track->Px();
517 fVarFloat[kVarPy] = track->Py();
518 fVarFloat[kVarPz] = track->Pz();
519 fVarFloat[kVarPxAtDCA] = (esdEvent ) ? ((AliESDMuonTrack*)track)->PxAtDCA() : ((AliAODTrack*)track)->PxAtDCA();
520 fVarFloat[kVarPyAtDCA] = (esdEvent ) ? ((AliESDMuonTrack*)track)->PyAtDCA() : ((AliAODTrack*)track)->PyAtDCA();
521 fVarFloat[kVarPzAtDCA] = (esdEvent ) ? ((AliESDMuonTrack*)track)->PzAtDCA() : ((AliAODTrack*)track)->PzAtDCA();
522 fVarFloat[kVarPtAtDCA] = TMath::Sqrt(fVarFloat[kVarPxAtDCA]*fVarFloat[kVarPxAtDCA] + fVarFloat[kVarPyAtDCA]*fVarFloat[kVarPyAtDCA]);
524 fVarFloat[kVarCharge] = track->Charge();
526 if ( ! fUseMC ) fTreeSingleMu->Fill();
530 if ( ! fUseMC ) continue;
532 fVarIntMC[kVarMotherType] = kUnknownPart;
534 AliMCParticle* matchedMCTrack = 0x0;
536 Int_t nMCtracks = mcEvent->GetNumberOfTracks();
537 for(Int_t imctrack=0; imctrack<nMCtracks; imctrack++){
538 mcTrack = (AliMCParticle*)mcEvent->GetTrack(imctrack);
539 if ( trackLabel == mcTrack->GetLabel() ) {
540 matchedMCTrack = mcTrack;
543 } // loop on MC tracks
545 if ( matchedMCTrack )
546 fVarIntMC[kVarMotherType] = RecoTrackMother(matchedMCTrack, mcEvent);
548 AliDebug(1, Form("Found mother %i", fVarIntMC[kVarMotherType]));
551 FillTriggerHistos(kHistoPtDCAMC, fVarInt[kVarMatchTrig], fVarIntMC[kVarMotherType], fVarFloat[kVarPt], fVarFloat[kVarDCA]);
552 FillTriggerHistos(kHistoPtVzMC, fVarInt[kVarMatchTrig], fVarIntMC[kVarMotherType], fVarFloat[kVarPt], fVarFloat[kVarIPVz]);
554 if ( matchedMCTrack ) {
555 fVarFloatMC[kVarPtMC] = matchedMCTrack->Pt();
556 FillTriggerHistos(kHistoPtResolutionMC, fVarInt[kVarMatchTrig], fVarIntMC[kVarMotherType], fVarFloat[kVarPt] - fVarFloatMC[kVarPtMC]);
558 fVarFloatMC[kVarPxMC] = matchedMCTrack->Px();
559 fVarFloatMC[kVarPyMC] = matchedMCTrack->Py();
560 fVarFloatMC[kVarPzMC] = matchedMCTrack->Pz();
561 fVarFloatMC[kVarEtaMC] = matchedMCTrack->Eta();
562 fVarFloatMC[kVarRapidityMC] = matchedMCTrack->Y();
563 fVarFloatMC[kVarVxMC] = matchedMCTrack->Xv();
564 fVarFloatMC[kVarVyMC] = matchedMCTrack->Yv();
565 fVarFloatMC[kVarVzMC] = matchedMCTrack->Zv();
566 fVarIntMC[kVarPdg] = matchedMCTrack->PdgCode();
569 if ( fFillTree ) fTreeSingleMuMC->Fill();
572 if ( fKeepAll && ( ( fVarInt[kVarIsMuon] + fVarInt[kVarIsGhost] ) == 0 ) ) {
573 // Fill event also if there is not muon (when explicitely required)
574 if ( ! fUseMC ) fTreeSingleMu->Fill();
575 else fTreeSingleMuMC->Fill();
578 if( strstr(fVarChar[kVarTrigMask],"MUON") && fVarInt[kVarIsMuon]==0 )
579 printf("WARNING: Muon trigger does not match tracker!\n");
581 Int_t histoIndex = GetHistoIndex(kNhistoTypes, 0) + kHistoMuonMultiplicity;
582 ((TH1F*)fHistoList->At(histoIndex))->Fill(fVarInt[kVarIsMuon]);
583 //if ( fVarInt[kVarIsMuon]>0 ) ((TH1F*)fHistoList->At(histoIndex))->Fill(2);
585 // Post final data. It will be written to a file with option "RECREATE"
586 PostData(1, fHistoList);
587 if ( fUseMC ) PostData(2, fHistoListMC);
590 PostData(3, fTreeSingleMuMC);
592 PostData(3, fTreeSingleMu);
596 //________________________________________________________________________
597 void AliAnalysisTaskSingleMu::Terminate(Option_t *) {
599 /// Draw some histogram at the end.
601 if (!gROOT->IsBatch()) {
602 fHistoList = dynamic_cast<TList*> (GetOutputData(1));
603 TCanvas *c1_SingleMu = new TCanvas("c1_SingleMu","Vz vs Pt",10,10,310,310);
604 c1_SingleMu->SetFillColor(10); c1_SingleMu->SetHighLightColor(10);
605 c1_SingleMu->SetLeftMargin(0.15); c1_SingleMu->SetBottomMargin(0.15);
606 Int_t histoIndex = GetHistoIndex(kHistoPtVz, kAllPtTrig);
607 ((TH2F*)fHistoList->At(histoIndex))->DrawCopy("COLZ");
611 //________________________________________________________________________
612 void AliAnalysisTaskSingleMu::FillTriggerHistos(Int_t histoIndex, Int_t matchTrig, Int_t motherType,
613 Float_t var1, Float_t var2, Float_t var3)
616 /// Fill all histograms passing the trigger cuts
619 Int_t nTrigs = TMath::Max(1, matchTrig);
620 TArrayI trigToFill(nTrigs);
621 trigToFill[0] = matchTrig;
622 for(Int_t itrig = 1; itrig < matchTrig; itrig++){
623 trigToFill[itrig] = itrig;
626 TList* histoList = (motherType < 0 ) ? fHistoList : fHistoListMC;
629 for(Int_t itrig = 0; itrig < nTrigs; itrig++){
630 Int_t currIndex = GetHistoIndex(histoIndex, trigToFill[itrig], motherType);
631 className = histoList->At(currIndex)->ClassName();
632 AliDebug(3, Form("matchTrig %i Fill %s", matchTrig, histoList->At(currIndex)->GetName()));
633 if (className.Contains("1"))
634 ((TH1F*)histoList->At(currIndex))->Fill(var1);
635 else if (className.Contains("2"))
636 ((TH2F*)histoList->At(currIndex))->Fill(var1, var2);
637 else if (className.Contains("3"))
638 ((TH3F*)histoList->At(currIndex))->Fill(var1, var2, var3);
640 AliWarning("Histogram not filled");
644 //________________________________________________________________________
645 Int_t AliAnalysisTaskSingleMu::RecoTrackMother(AliMCParticle* mcTrack, AliMCEvent* mcEvent)
648 /// Find track mother from kinematics
651 Int_t recoPdg = mcTrack->PdgCode();
653 Bool_t isMuon = (TMath::Abs(recoPdg) == 13) ? kTRUE : kFALSE;
655 // Track is not a muon
656 if ( ! isMuon ) return kRecoHadron;
658 Int_t imother = mcTrack->GetMother();
661 return kPrimaryMu; // Drell-Yan Muon
663 Int_t igrandma = imother;
665 AliMCParticle* motherPart = (AliMCParticle*)mcEvent->GetTrack(imother);
666 Int_t motherPdg = motherPart->PdgCode();
668 // Track is an heavy flavor muon
669 Int_t absPdg = TMath::Abs(motherPdg);
670 if(absPdg/100==5 || absPdg/1000==5) {
673 if(absPdg/100==4 || absPdg/1000==4){
674 Int_t newMother = -1;
676 AliInfo("\nFound candidate B->C->mu. History:\n");
678 printf("- %2i ", igrandma);
680 Int_t absGrandMotherPdg = TMath::Abs(motherPart->PdgCode());
681 while ( absGrandMotherPdg > 10 ) {
682 igrandma = ((AliMCParticle*)mcEvent->GetTrack(igrandma))->GetMother();
683 if( igrandma < 0 ) break;
684 printf("- %2i ", igrandma);
685 mcEvent->GetTrack(igrandma)->Print();
686 absGrandMotherPdg = TMath::Abs(((AliMCParticle*)mcEvent->GetTrack(igrandma))->PdgCode());
689 if (absGrandMotherPdg==5) newMother = kBeautyMu; // Charm from beauty
690 else if (absGrandMotherPdg==4) newMother = kCharmMu;
693 AliWarning("Mother not correctly found! Set to charm!\n");
694 newMother = kCharmMu;
700 Int_t nPrimaries = mcEvent->Stack()->GetNprimary();
702 // Track is a bkg. muon
703 if (imother<nPrimaries) {
711 //________________________________________________________________________
712 Int_t AliAnalysisTaskSingleMu::GetHistoIndex(Int_t histoTypeIndex, Int_t trigIndex, Int_t srcIndex)
715 /// Get histogram index in the list
717 if ( srcIndex < 0 ) return kNtrigCuts * histoTypeIndex + trigIndex;
720 kNtrackSources * kNtrigCuts * histoTypeIndex +
721 kNtrackSources * trigIndex +
725 //________________________________________________________________________
726 void AliAnalysisTaskSingleMu::Reset(Bool_t keepGlobal)
731 Int_t lastVarFloat = ( keepGlobal ) ? kVarIPVx : kNvarFloat;
732 for(Int_t ivar=0; ivar<lastVarFloat; ivar++){
733 fVarFloat[ivar] = 0.;
735 Int_t lastVarInt = ( keepGlobal ) ? kVarPassPhysicsSelection : kNvarInt;
736 for(Int_t ivar=0; ivar<lastVarInt; ivar++){
739 fVarInt[kVarIsMuon] = 0;
740 fVarInt[kVarIsGhost] = 0;
743 for(Int_t ivar=0; ivar<kNvarChar; ivar++){
744 //sprintf(fVarChar[ivar],"%253s","");
745 sprintf(fVarChar[ivar]," ");
747 for(Int_t ivar=0; ivar<kNvarUInt; ivar++){
752 for(Int_t ivar=0; ivar<kNvarFloatMC; ivar++){
753 fVarFloatMC[ivar] = 0.;
755 for(Int_t ivar=0; ivar<kNvarIntMC; ivar++){
756 fVarIntMC[ivar] = -1;