1 /**************************************************************************
2 * Copyright(c) 1998-1999, 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 #include <Riostream.h>
24 #include "TObjArray.h"
30 #include "TObjString.h"
33 #include "AliESDEvent.h"
34 #include "AliESDMuonTrack.h"
35 #include "AliESDMuonCluster.h"
36 #include "AliESDInputHandler.h"
37 #include "AliESDVZERO.h"
40 #include "AliAnalysisTaskSE.h"
41 #include "AliAnalysisDataSlot.h"
42 #include "AliAnalysisManager.h"
43 #include "AliAnalysisTaskMuonQA.h"
44 #include "AliCounterCollection.h"
46 ClassImp(AliAnalysisTaskMuonQA)
48 const Int_t AliAnalysisTaskMuonQA::nCh = 10;
50 const Int_t AliAnalysisTaskMuonQA::nDE = 1100;
52 const Float_t AliAnalysisTaskMuonQA::dMax[5] = {176.6, 229.0, 308.84, 418.2, 522.0}; // cm
54 //________________________________________________________________________
55 AliAnalysisTaskMuonQA::AliAnalysisTaskMuonQA() :
63 fSelectPhysics(kFALSE),
64 fSelectTrigger(kFALSE),
66 fSelectMatched(kFALSE),
69 fSelectTriggerClass(0x0)
74 //________________________________________________________________________
75 AliAnalysisTaskMuonQA::AliAnalysisTaskMuonQA(const char *name) :
76 AliAnalysisTaskSE(name),
83 fSelectPhysics(kFALSE),
84 fSelectTrigger(kFALSE),
86 fSelectMatched(kFALSE),
89 fSelectTriggerClass(0x0)
93 // Output slot #1 writes into a TObjArray container
94 DefineOutput(1,TObjArray::Class());
95 // Output slot #2 writes into a TObjArray container
96 DefineOutput(2,TObjArray::Class());
97 // Output slot #3 writes track counters
98 DefineOutput(3,AliCounterCollection::Class());
99 // Output slot #4 writes event counters
100 DefineOutput(4,AliCounterCollection::Class());
101 // Output slot #5 writes normalized histograms
102 DefineOutput(5,TObjArray::Class());
105 //________________________________________________________________________
106 AliAnalysisTaskMuonQA::~AliAnalysisTaskMuonQA()
109 if (!AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
112 delete fTrackCounters;
113 delete fEventCounters;
116 delete fTriggerClass;
117 delete fSelectTriggerClass;
120 //___________________________________________________________________________
121 void AliAnalysisTaskMuonQA::UserCreateOutputObjects()
123 /// Create histograms and counters
125 // set the list of trigger classes with corresponding short names
126 fTriggerClass = new TMap(20);
127 fTriggerClass->SetOwnerKeyValue();
128 // p-p trigger classes
129 fTriggerClass->Add(new TObjString("CBEAMB"), new TObjString("CBEAMB"));
130 fTriggerClass->Add(new TObjString("CINT1B-ABCE-NOPF-ALL"), new TObjString("CINT1B"));
131 fTriggerClass->Add(new TObjString("CMUS1B-ABCE-NOPF-MUON"), new TObjString("CMUS1B"));
132 fTriggerClass->Add(new TObjString("CINT1[AC]-"), new TObjString("CINT1AC"));
133 fTriggerClass->Add(new TObjString("CMUS1[AC]-"), new TObjString("CMUS1AC"));
134 fTriggerClass->Add(new TObjString("CINT1-E-"), new TObjString("CINT1E"));
135 fTriggerClass->Add(new TObjString("CINT5-E-"), new TObjString("CINT1E"));
136 fTriggerClass->Add(new TObjString("CMUS1-E-"), new TObjString("CMUS1E"));
137 fTriggerClass->Add(new TObjString("CMUS5-E-"), new TObjString("CMUS1E"));
138 fTriggerClass->Add(new TObjString("CINT1-B-"), new TObjString("CINT1B"));
139 fTriggerClass->Add(new TObjString("CINT5-B-"), new TObjString("CINT1B"));
140 fTriggerClass->Add(new TObjString("CMUS1-B-"), new TObjString("CMUS1B"));
141 fTriggerClass->Add(new TObjString("CMUS5-B-"), new TObjString("CMUS1B"));
142 fTriggerClass->Add(new TObjString("CINT1-AC-"), new TObjString("CINT1AC"));
143 fTriggerClass->Add(new TObjString("CINT5-AC-"), new TObjString("CINT1AC"));
144 fTriggerClass->Add(new TObjString("CMUS1-AC-"), new TObjString("CMUS1AC"));
145 fTriggerClass->Add(new TObjString("CMUS5-AC-"), new TObjString("CMUS1AC"));
146 fTriggerClass->Add(new TObjString("CSH1-B-"), new TObjString("CSH1B"));
147 // Pb-Pb trigger classes
148 TString side[4] = {"B", "A", "C", "E"};
149 for (Int_t i = 0; i < 4; i++) {
150 fTriggerClass->Add(new TObjString(Form("CMBACS2-%s-", side[i].Data())), new TObjString(Form("CMBACS2-%s", side[i].Data())));
151 fTriggerClass->Add(new TObjString(Form("CMBS2A-%s-", side[i].Data())), new TObjString(Form("CMBS2A-%s", side[i].Data())));
152 fTriggerClass->Add(new TObjString(Form("CMBS2C-%s-", side[i].Data())), new TObjString(Form("CMBS2C-%s", side[i].Data())));
153 fTriggerClass->Add(new TObjString(Form("CMBAC-%s-", side[i].Data())), new TObjString(Form("CMBAC-%s", side[i].Data())));
154 fTriggerClass->Add(new TObjString(Form("C0SMH-%s-", side[i].Data())), new TObjString(Form("C0SMH-%s", side[i].Data())));
157 // set the list of trigger classes that can be selected to fill histograms (in case the physics selection is not used)
158 fSelectTriggerClass = new TList();
159 fSelectTriggerClass->SetOwner();
160 // p-p trigger classes
161 fSelectTriggerClass->AddLast(new TObjString("CINT1B-ABCE-NOPF-ALL")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
162 fSelectTriggerClass->AddLast(new TObjString("CMUS1B-ABCE-NOPF-MUON")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUON);
163 fSelectTriggerClass->AddLast(new TObjString("CINT1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
164 fSelectTriggerClass->AddLast(new TObjString("CINT5-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
165 fSelectTriggerClass->AddLast(new TObjString("CMUS1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUON);
166 fSelectTriggerClass->AddLast(new TObjString("CMUS5-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUON);
167 fSelectTriggerClass->AddLast(new TObjString("CSH1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kHighMult);
168 // Pb-Pb trigger classes
169 fSelectTriggerClass->AddLast(new TObjString("CMBACS2-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
170 fSelectTriggerClass->AddLast(new TObjString("CMBS2A-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
171 fSelectTriggerClass->AddLast(new TObjString("CMBS2C-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
172 fSelectTriggerClass->AddLast(new TObjString("CMBAC-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
173 fSelectTriggerClass->AddLast(new TObjString("C0SMH-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kHighMult);
176 fList = new TObjArray(2000);
178 fListExpert = new TObjArray(2000);
179 fListExpert->SetOwner();
182 TH1F* hNTracks = new TH1F("hNTracks", "number of tracks;n_{tracks}", 20, 0., 20.);
183 fList->AddAtAndExpand(hNTracks, kNTracks);
185 TH1F* hMatchTrig = new TH1F("hMatchTrig", "number of tracks matched with trigger;n_{tracks}", 20, 0., 20.);
186 fList->AddAtAndExpand(hMatchTrig, kMatchTrig);
188 TH1F* hSign = new TH1F("hSign", "track sign;sign", 3, -1.5, 1.5);
189 fList->AddAtAndExpand(hSign, kSign);
191 TH1F* hDCA = new TH1F("hDCA", "DCA distribution;DCA (cm)", 500, 0., 500.);
192 fList->AddAtAndExpand(hDCA, kDCA);
194 TH1F* hP = new TH1F("hP", "momentum distribution;p (GeV/c)", 300, 0., 300.);
195 fList->AddAtAndExpand(hP, kP);
197 TH1F* hPMuPlus = new TH1F("hPMuPlus", "momentum distribution of #mu^{+};p (GeV/c)", 300, 0., 300.);
198 fList->AddAtAndExpand(hPMuPlus, kPMuPlus);
200 TH1F* hPMuMinus = new TH1F("hPMuMinus", "momentum distribution of #mu^{-};p (GeV/c)", 300, 0., 300.);
201 fList->AddAtAndExpand(hPMuMinus, kPMuMinus);
203 TH1F* hPt = new TH1F("hPt", "transverse momentum distribution;p_{t} (GeV/c)", 300, 0., 30);
204 fList->AddAtAndExpand(hPt, kPt);
206 TH1F* hPtMuPlus = new TH1F("hPtMuPlus", "transverse momentum distribution of #mu^{+};p_{t} (GeV/c)", 300, 0., 30);
207 fList->AddAtAndExpand(hPtMuPlus, kPtMuPlus);
209 TH1F* hPtMuMinus = new TH1F("hPtMuMinus", "transverse momentum distribution of #mu^{-};p_{t} (GeV/c)", 300, 0., 30);
210 fList->AddAtAndExpand(hPtMuMinus, kPtMuMinus);
212 TH1F* hRapidity = new TH1F("hRapidity", "rapidity distribution;rapidity", 200, -4.5, -2.);
213 fList->AddAtAndExpand(hRapidity, kRapidity);
215 TH1F* hThetaX = new TH1F("hThetaX", "#theta_{X} distribution;#theta_{X} (degree)", 360, -180., 180);
216 fList->AddAtAndExpand(hThetaX, kThetaX);
218 TH1F* hThetaY = new TH1F("hThetaY", "#theta_{Y} distribution;#theta_{Y} (degree)", 360, -180., 180);
219 fList->AddAtAndExpand(hThetaY, kThetaY);
221 TH1F* hChi2 = new TH1F("hChi2", "normalized #chi^{2} distribution;#chi^{2} / ndf", 500, 0., 50.);
222 fList->AddAtAndExpand(hChi2, kChi2);
224 TH1F* hProbChi2 = new TH1F("hProbChi2", "distribution of probability of #chi^{2};prob(#chi^{2})", 100, 0., 1.);
225 fList->AddAtAndExpand(hProbChi2, kProbChi2);
228 TH1F* hNClustersPerTrack = new TH1F("hNClustersPerTrack", "number of associated clusters per track;n_{clusters}", 20, 0., 20.);
229 fList->AddAtAndExpand(hNClustersPerTrack, kNClustersPerTrack);
231 TH1F* hNChamberHitPerTrack = new TH1F("hNChamberHitPerTrack", "number of chambers hit per track;n_{chamber hit}", 15, 0., 15.);
232 fList->AddAtAndExpand(hNChamberHitPerTrack, kNChamberHitPerTrack);
234 TH1F* hNClustersPerCh = new TH1F("hNClustersPerCh", "averaged number of clusters per chamber per track;chamber ID;<n_{clusters}>", nCh, -0.5, nCh-0.5);
235 hNClustersPerCh->Sumw2();
236 hNClustersPerCh->SetOption("P");
237 hNClustersPerCh->SetMarkerStyle(kFullDotMedium);
238 hNClustersPerCh->SetMarkerColor(kBlue);
239 fListExpert->AddAtAndExpand(hNClustersPerCh, kNClustersPerCh);
241 TH1F* hNClustersPerDE = new TH1F("hNClustersPerDE", "averaged number of clusters per DE per track;DetElem ID;<n_{clusters}>", nDE+1, -0.5, nDE+0.5);
242 hNClustersPerDE->Sumw2();
243 hNClustersPerDE->SetOption("P");
244 hNClustersPerDE->SetMarkerStyle(kFullDotMedium);
245 hNClustersPerDE->SetMarkerColor(kBlue);
246 fListExpert->AddAtAndExpand(hNClustersPerDE, kNClustersPerDE);
248 for (Int_t i = 0; i < nCh; i++) {
249 Float_t rMax = 0.5*dMax[i/2];
250 TH2F* hClusterHitMapInCh = new TH2F(Form("hClusterHitMapInCh%d",i+1), Form("cluster position distribution in chamber %d;X (cm);Y (cm)",i+1),
251 100, -rMax, rMax, 100, -rMax, rMax);
252 fListExpert->AddAtAndExpand(hClusterHitMapInCh, kClusterHitMapInCh+i);
254 TH1F* hClusterChargeInCh = new TH1F(Form("hClusterChargeInCh%d",i+1), Form("cluster charge distribution in chamber %d;charge (fC)",i+1), 100, 0., 1000.);
255 fListExpert->AddAtAndExpand(hClusterChargeInCh, kClusterChargeInCh+i);
257 TH1F* hClusterSizeInCh = new TH1F(Form("hClusterSizeInCh%d",i+1), Form("cluster size distribution in chamber %d;size (n_{pads})",i+1), 200, 0., 200.);
258 fListExpert->AddAtAndExpand(hClusterSizeInCh, kClusterSizeInCh+i);
261 TH2F* hClusterChargePerDE = new TH2F("hClusterChargePerDE", "cluster charge distribution per DE;DetElem ID;charge (fC)", nDE+1, -0.5, nDE+0.5, 100, 0., 1000.);
262 fListExpert->AddAtAndExpand(hClusterChargePerDE, kClusterChargePerDE);
264 TH2F* hClusterSizePerDE = new TH2F("hClusterSizePerDE", "cluster size distribution per DE;DetElem ID;size (n_{pads})", nDE+1, -0.5, nDE+0.5, 200, 0., 200.);
265 fListExpert->AddAtAndExpand(hClusterSizePerDE, kClusterSizePerDE);
267 // initialize track counters
268 fTrackCounters = new AliCounterCollection("trackCounters");
269 fTrackCounters->AddRubric("track", "trackeronly/triggeronly/matched");
270 fTrackCounters->AddRubric("trigger", 1000000);
271 fTrackCounters->AddRubric("run", 1000000);
272 fTrackCounters->AddRubric("selected", "yes/no");
273 fTrackCounters->AddRubric("triggerRO", "good/bad");
274 fTrackCounters->AddRubric("v0mult", "low/int/high/any");
275 fTrackCounters->AddRubric("charge", "pos/neg/any");
276 fTrackCounters->AddRubric("pt", "low/high/any");
277 fTrackCounters->AddRubric("acc", "in/out");
278 fTrackCounters->Init();
280 // initialize event counters
281 fEventCounters = new AliCounterCollection("eventCounters");
282 fEventCounters->AddRubric("event", "muon/any");
283 fEventCounters->AddRubric("trigger", 1000000);
284 fEventCounters->AddRubric("run", 1000000);
285 fEventCounters->AddRubric("selected", "yes/no");
286 fEventCounters->AddRubric("triggerRO", "good/bad");
287 fEventCounters->AddRubric("v0mult", "low/int/high/any");
288 fEventCounters->Init();
290 // Post data at least once per task to ensure data synchronisation (required for merging)
292 PostData(2, fListExpert);
293 PostData(3, fTrackCounters);
294 PostData(4, fEventCounters);
297 //________________________________________________________________________
298 void AliAnalysisTaskMuonQA::UserExec(Option_t *)
300 /// Called for each event
302 AliESDEvent* fESD = dynamic_cast<AliESDEvent*>(InputEvent());
304 Printf("ERROR: fESD not available");
308 // check physics selection
309 UInt_t triggerWord = (fInputHandler) ? fInputHandler->IsEventSelected() : 0;
310 Bool_t isPhysicsSelected = (triggerWord != 0);
311 TString selected = isPhysicsSelected ? "selected:yes" : "selected:no";
313 // check trigger selection
314 TString FiredTriggerClasses = fESD->GetFiredTriggerClasses();
315 if (!fSelectPhysics) triggerWord = BuildTriggerWord(FiredTriggerClasses);
316 Bool_t isTriggerSelected = ((triggerWord & fTriggerMask) != 0);
318 // get the V0 multiplicity (except for p-p)
319 AliESDVZERO* v0Data = fESD->GetVZEROData();
321 if (v0Data && strcmp(fESD->GetBeamType(),"p-p"))
322 for (Int_t i = 0 ; i < 64 ; i++) v0Mult += v0Data->GetMultiplicity(i);
324 listV0MultKey.SetOwner();
325 listV0MultKey.AddLast(new TObjString("v0mult:any"));
326 //if (v0Mult > 239. && v0Mult < 559.) listV0MultKey.AddLast(new TObjString("v0mult:low"));
327 if (v0Mult >= 239. && v0Mult < 1165.) listV0MultKey.AddLast(new TObjString("v0mult:low"));
328 else if (v0Mult >= 1165. && v0Mult < 12191.) listV0MultKey.AddLast(new TObjString("v0mult:int"));
329 else if (v0Mult >= 12191. && v0Mult < 20633.) listV0MultKey.AddLast(new TObjString("v0mult:high"));
330 TIter nextV0MultKey(&listV0MultKey);
332 // first loop over tracks to check for trigger readout problem
333 Int_t maxTriggerRO = (!strcmp(fESD->GetBeamType(),"p-p")) ? 10 : 1000;
334 Int_t nTracks = (Int_t) fESD->GetNumberOfMuonTracks();
335 Int_t nTriggerTracks = 0;
336 for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack)
337 if (fESD->GetMuonTrack(iTrack)->ContainTriggerData()) nTriggerTracks++;
338 TString triggerRO = (nTriggerTracks < maxTriggerRO) ? "triggerRO:good" : "triggerRO:bad";
340 // --- fill event counters ---
342 // build the list of trigger cases
343 TList* triggerCases = BuildListOfTriggerCases(FiredTriggerClasses);
345 // loop over trigger cases
346 TObjString* triggerKey = 0x0;
347 TIter nextTriggerCase(triggerCases);
348 while ((triggerKey = static_cast<TObjString*>(nextTriggerCase()))) {
350 // loop over V0Mult cases
351 TObjString* v0MultKey = 0x0;
352 nextV0MultKey.Reset();
353 while ((v0MultKey = static_cast<TObjString*>(nextV0MultKey()))) {
356 fEventCounters->Count(Form("event:any/%s/run:%d/%s/%s/%s", triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), v0MultKey->GetName()));
359 if (nTracks > 0) fEventCounters->Count(Form("event:muon/%s/run:%d/%s/%s/%s", triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), v0MultKey->GetName()));
365 // second loop over tracks to fill histograms and track counters
366 Int_t nSelectedTrackerTracks = 0;
367 Int_t nSelectedTrackMatchTrig = 0;
368 Int_t nPVTracks = fESD->GetPrimaryVertex()->GetNContributors();
369 for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack) {
372 AliESDMuonTrack* esdTrack = fESD->GetMuonTrack(iTrack);
374 // --- fill track counters ---
376 // define the key words
377 TString trackKey = "track:";
378 TString chargeKey = "charge:";
379 TString accKey = "acc:";
380 Bool_t lowPt = kFALSE;
381 Bool_t highPt = kFALSE;
382 if (esdTrack->ContainTrackerData()) {
384 if (esdTrack->ContainTriggerData()) trackKey += "matched";
385 else trackKey += "trackeronly";
387 Short_t trackCharge = esdTrack->Charge();
388 if (trackCharge < 0) chargeKey += "neg";
389 else chargeKey += "pos";
391 Double_t thetaTrackAbsEnd = TMath::ATan(esdTrack->GetRAtAbsorberEnd()/505.) * TMath::RadToDeg();
392 Double_t trackPt = esdTrack->Pt();
393 if (trackPt > 1. && nPVTracks>0 && thetaTrackAbsEnd>2. ) lowPt = kTRUE;
394 if (trackPt > 2. && nPVTracks>0 && thetaTrackAbsEnd>2. ) highPt = kTRUE;
396 Double_t eta = esdTrack->Eta();
397 if (thetaTrackAbsEnd < 2. || thetaTrackAbsEnd > 9. || eta < -4. || eta > -2.5) accKey += "out";
402 trackKey += "triggeronly";
403 chargeKey = ""; // ghost have no charge specified
404 accKey += "out"; // ghost are labelled out of the acceptance
408 // loop over trigger cases and fill counters
409 nextTriggerCase.Reset();
410 while ((triggerKey = static_cast<TObjString*>(nextTriggerCase()))) {
412 // loop over V0Mult cases
413 TObjString* v0MultKey = 0x0;
414 nextV0MultKey.Reset();
415 while ((v0MultKey = static_cast<TObjString*>(nextV0MultKey()))) {
417 // any charge / any pt
418 fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/charge:any/pt:any/%s/%s", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), v0MultKey->GetName(), accKey.Data()));
420 // any charge / specific pt
421 if (lowPt) fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/charge:any/pt:low/%s/%s", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), v0MultKey->GetName(), accKey.Data()));
422 if (highPt) fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/charge:any/pt:high/%s/%s", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), v0MultKey->GetName(), accKey.Data()));
424 if (!chargeKey.IsNull()) {
426 // specific charge / any pt
427 fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/%s/pt:any/%s/%s", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), chargeKey.Data(), v0MultKey->GetName(), accKey.Data()));
429 // specific charge / specific pt
430 if (lowPt) fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/%s/pt:low/%s/%s", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), chargeKey.Data(), v0MultKey->GetName(), accKey.Data()));
431 if (highPt) fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/%s/pt:high/%s/%s", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), chargeKey.Data(), v0MultKey->GetName(), accKey.Data()));
439 // --- apply selections and fill histograms with selected tracks ---
442 if (!esdTrack->ContainTrackerData()) continue;
444 // select on "physics" before filling histograms
445 if (fSelectPhysics && !isPhysicsSelected) continue;
447 // select on trigger before filling histograms
448 if (fSelectTrigger && !isTriggerSelected) continue;
450 // select on track charge
451 if (fSelectCharge*esdTrack->Charge() < 0) continue;
453 // select on track matching
454 if (fSelectMatched && !esdTrack->ContainTriggerData()) continue;
456 // skip tracks that do not pass the acceptance cuts if required
457 if (fApplyAccCut && accKey.EndsWith("out")) continue;
459 nSelectedTrackerTracks++;
460 if (esdTrack->ContainTriggerData()) nSelectedTrackMatchTrig++;
462 Double_t trackP = esdTrack->P();
463 Double_t trackPt = esdTrack->Pt();
464 Short_t trackCharge = esdTrack->Charge();
465 ((TH1F*)fList->UncheckedAt(kP))->Fill(trackP);
466 ((TH1F*)fList->UncheckedAt(kPt))->Fill(trackPt);
467 if (trackCharge < 0) {
468 ((TH1F*)fList->UncheckedAt(kPMuMinus))->Fill(trackP);
469 ((TH1F*)fList->UncheckedAt(kPtMuMinus))->Fill(trackPt);
471 ((TH1F*)fList->UncheckedAt(kPMuPlus))->Fill(trackP);
472 ((TH1F*)fList->UncheckedAt(kPtMuPlus))->Fill(trackPt);
474 ((TH1F*)fList->UncheckedAt(kRapidity))->Fill(esdTrack->Y());
475 Int_t ndf = 2 * esdTrack->GetNHit() - 5;
476 ((TH1F*)fList->UncheckedAt(kChi2))->Fill(esdTrack->GetChi2()/ndf);
477 ((TH1F*)fList->UncheckedAt(kProbChi2))->Fill(TMath::Prob(esdTrack->GetChi2(),ndf));
478 ((TH1F*)fList->UncheckedAt(kThetaX))->Fill(ChangeThetaRange(esdTrack->GetThetaXUncorrected()));
479 ((TH1F*)fList->UncheckedAt(kThetaY))->Fill(ChangeThetaRange(esdTrack->GetThetaYUncorrected()));
480 ((TH1F*)fList->UncheckedAt(kNClustersPerTrack))->Fill(esdTrack->GetNHit());
481 ((TH1F*)fList->UncheckedAt(kSign))->Fill(trackCharge);
482 ((TH1F*)fList->UncheckedAt(kDCA))->Fill(esdTrack->GetDCA());
484 Int_t nChamberHit = 0;
485 for (Int_t ich=0; ich<10; ich++) if (esdTrack->IsInMuonClusterMap(ich)) nChamberHit++;
486 ((TH1F*)fList->UncheckedAt(kNChamberHitPerTrack))->Fill(nChamberHit);
488 // what follows concern clusters
489 if(!esdTrack->ClustersStored()) continue;
491 AliESDMuonCluster *esdCluster = (AliESDMuonCluster*) esdTrack->GetClusters().First();
494 Int_t chId = esdCluster->GetChamberId();
495 Int_t deId = esdCluster->GetDetElemId();
497 ((TH1F*)fListExpert->UncheckedAt(kNClustersPerCh))->Fill(chId);
498 ((TH1F*)fListExpert->UncheckedAt(kNClustersPerDE))->Fill(deId);
500 ((TH1F*)fListExpert->UncheckedAt(kClusterHitMapInCh+chId))->Fill(esdCluster->GetX(), esdCluster->GetY());
502 ((TH1F*)fListExpert->UncheckedAt(kClusterChargeInCh+chId))->Fill(esdCluster->GetCharge());
503 ((TH1F*)fListExpert->UncheckedAt(kClusterChargePerDE))->Fill(deId, esdCluster->GetCharge());
505 if (esdCluster->PadsStored()) { // discard clusters with pad not stored in ESD
506 ((TH1F*)fListExpert->UncheckedAt(kClusterSizeInCh+chId))->Fill(esdCluster->GetNPads());
507 ((TH1F*)fListExpert->UncheckedAt(kClusterSizePerDE))->Fill(deId, esdCluster->GetNPads());
510 esdCluster = (AliESDMuonCluster*) esdTrack->GetClusters().After(esdCluster);
515 if ((!fSelectPhysics || isPhysicsSelected) && (!fSelectTrigger || isTriggerSelected)) {
516 ((TH1F*)fList->UncheckedAt(kNTracks))->Fill(nSelectedTrackerTracks);
517 ((TH1F*)fList->UncheckedAt(kMatchTrig))->Fill(nSelectedTrackMatchTrig);
523 // Post final data. It will be written to a file with option "RECREATE"
525 PostData(2, fListExpert);
526 PostData(3, fTrackCounters);
527 PostData(4, fEventCounters);
530 //________________________________________________________________________
531 void AliAnalysisTaskMuonQA::Terminate(Option_t *)
533 /// Normalize histograms
534 /// Draw result to the screen
538 fTrackCounters = static_cast<AliCounterCollection*>(GetOutputData(3));
539 fEventCounters = static_cast<AliCounterCollection*>(GetOutputData(4));
540 if (fTrackCounters && fEventCounters) {
541 if (!gROOT->IsBatch()) {
542 cout<<"whole statistics without selection:"<<endl;
543 fEventCounters->Print("trigger/event");
544 fTrackCounters->Print("trigger/track");
545 cout<<"whole statistics of selected events:"<<endl;
546 fEventCounters->Print("trigger/event","selected:yes");
547 fTrackCounters->Print("trigger/track","selected:yes");
549 fEventCounters->Draw("event","trigger","");
551 fTrackCounters->Draw("track","trigger","");
553 fEventCounters->Draw("event","trigger","selected:yes");
555 fTrackCounters->Draw("track","trigger","selected:yes");
559 // recover output histograms
560 fList = static_cast<TObjArray*>(GetOutputData(1));
561 fListExpert = static_cast<TObjArray*>(GetOutputData(2));
562 if (!fList || !fListExpert) return;
564 // create summary plots
565 fListNorm = new TObjArray(1000);
566 fListNorm->SetOwner();
568 // mean/dispersion of cluster charge per chamber/DE
569 TH1F* hClusterChargePerChMean = new TH1F("hClusterChargePerChMean", "cluster mean charge per chamber;chamber ID;<charge> (fC)", nCh, -0.5, nCh-0.5);
570 hClusterChargePerChMean->SetOption("P");
571 hClusterChargePerChMean->SetMarkerStyle(kFullDotMedium);
572 hClusterChargePerChMean->SetMarkerColor(kBlue);
573 fListNorm->AddAtAndExpand(hClusterChargePerChMean, kClusterChargePerChMean);
575 TH1F* hClusterChargePerChSigma = new TH1F("hClusterChargePerChSigma", "cluster charge dispersion per chamber;chamber ID;#sigma_{charge} (fC)", nCh, -0.5, nCh-0.5);
576 hClusterChargePerChSigma->SetOption("P");
577 hClusterChargePerChSigma->SetMarkerStyle(kFullDotMedium);
578 hClusterChargePerChSigma->SetMarkerColor(kBlue);
579 fListNorm->AddAtAndExpand(hClusterChargePerChSigma, kClusterChargePerChSigma);
581 TH1F* hClusterChargePerDEMean = new TH1F("hClusterChargePerDEMean", "cluster mean charge per DE;DetElem ID;<charge> (fC)", nDE+1, -0.5, nDE+0.5);
582 hClusterChargePerDEMean->SetOption("P");
583 hClusterChargePerDEMean->SetMarkerStyle(kFullDotMedium);
584 hClusterChargePerDEMean->SetMarkerColor(kBlue);
585 fListNorm->AddAtAndExpand(hClusterChargePerDEMean, kClusterChargePerDEMean);
587 TH1F* hClusterChargePerDESigma = new TH1F("hClusterChargePerDESigma", "cluster charge dispersion per DE;DetElem ID;#sigma_{charge} (fC)", nDE+1, -0.5, nDE+0.5);
588 hClusterChargePerDESigma->SetOption("P");
589 hClusterChargePerDESigma->SetMarkerStyle(kFullDotMedium);
590 hClusterChargePerDESigma->SetMarkerColor(kBlue);
591 fListNorm->AddAtAndExpand(hClusterChargePerDESigma, kClusterChargePerDESigma);
593 // mean/dispersion of cluster size per chamber/DE
594 TH1F* hClusterSizePerChMean = new TH1F("hClusterSizePerChMean", "cluster mean size per chamber;chamber ID;<size> (n_{pads})", nCh, -0.5, nCh-0.5);
595 hClusterSizePerChMean->SetOption("P");
596 hClusterSizePerChMean->SetMarkerStyle(kFullDotMedium);
597 hClusterSizePerChMean->SetMarkerColor(kBlue);
598 fListNorm->AddAtAndExpand(hClusterSizePerChMean, kClusterSizePerChMean);
600 TH1F* hClusterSizePerChSigma = new TH1F("hClusterSizePerChSigma", "cluster size dispersion per chamber;chamber ID;#sigma_{size} (n_{pads})", nCh, -0.5, nCh-0.5);
601 hClusterSizePerChSigma->SetOption("P");
602 hClusterSizePerChSigma->SetMarkerStyle(kFullDotMedium);
603 hClusterSizePerChSigma->SetMarkerColor(kBlue);
604 fListNorm->AddAtAndExpand(hClusterSizePerChSigma, kClusterSizePerChSigma);
606 TH1F* hClusterSizePerDEMean = new TH1F("hClusterSizePerDEMean", "cluster mean size per DE;DetElem ID;<size> (n_{pads})", nDE+1, -0.5, nDE+0.5);
607 hClusterSizePerDEMean->SetOption("P");
608 hClusterSizePerDEMean->SetMarkerStyle(kFullDotMedium);
609 hClusterSizePerDEMean->SetMarkerColor(kBlue);
610 fListNorm->AddAtAndExpand(hClusterSizePerDEMean, kClusterSizePerDEMean);
612 TH1F* hClusterSizePerDESigma = new TH1F("hClusterSizePerDESigma", "cluster size dispersion per DE;DetElem ID;#sigma_{size} (n_{pads})", nDE+1, -0.5, nDE+0.5);
613 hClusterSizePerDESigma->SetOption("P");
614 hClusterSizePerDESigma->SetMarkerStyle(kFullDotMedium);
615 hClusterSizePerDESigma->SetMarkerColor(kBlue);
616 fListNorm->AddAtAndExpand(hClusterSizePerDESigma, kClusterSizePerDESigma);
618 // normalize histograms
619 Float_t nTracks = ((TH1F*)fList->UncheckedAt(kNClustersPerTrack))->GetEntries();
621 ((TH1F*)fListExpert->UncheckedAt(kNClustersPerCh))->Scale(1./nTracks);
622 ((TH1F*)fListExpert->UncheckedAt(kNClustersPerDE))->Scale(1./nTracks);
624 fListNorm->AddAtAndExpand(((TH1F*)fListExpert->UncheckedAt(kNClustersPerCh))->Clone(), kNClustersPerChPerTrack);
625 fListNorm->AddAtAndExpand(((TH1F*)fListExpert->UncheckedAt(kNClustersPerDE))->Clone(), kNClustersPerDEPerTrack);
627 // fill summary plots per chamber
628 for (Int_t iCh = 0; iCh < nCh; iCh++) {
630 TH1* hClusterChargeInCh = ((TH1F*)fListExpert->UncheckedAt(kClusterChargeInCh+iCh));
631 hClusterChargePerChMean->SetBinContent(iCh+1, hClusterChargeInCh->GetMean());
632 hClusterChargePerChMean->SetBinError(iCh+1, hClusterChargeInCh->GetMeanError());
633 hClusterChargePerChSigma->SetBinContent(iCh+1, hClusterChargeInCh->GetRMS());
634 hClusterChargePerChSigma->SetBinError(iCh+1, hClusterChargeInCh->GetRMSError());
636 TH1* hClusterSizeInCh = ((TH1F*)fListExpert->UncheckedAt(kClusterSizeInCh+iCh));
637 hClusterSizePerChMean->SetBinContent(iCh+1, hClusterSizeInCh->GetMean());
638 hClusterSizePerChMean->SetBinError(iCh+1, hClusterSizeInCh->GetMeanError());
639 hClusterSizePerChSigma->SetBinContent(iCh+1, hClusterSizeInCh->GetRMS());
640 hClusterSizePerChSigma->SetBinError(iCh+1, hClusterSizeInCh->GetRMSError());
644 // fill summary plots per DE
645 TH2F* hClusterChargePerDE = ((TH2F*)fListExpert->UncheckedAt(kClusterChargePerDE));
646 TH2F* hClusterSizePerDE = ((TH2F*)fListExpert->UncheckedAt(kClusterSizePerDE));
647 for (Int_t iDE = 1; iDE < nDE+1; iDE++) {
649 TH1D *tmp = hClusterChargePerDE->ProjectionY("tmp",iDE,iDE,"e");
650 if (tmp->GetEntries() > 10.) {
651 hClusterChargePerDEMean->SetBinContent(iDE, tmp->GetMean());
652 hClusterChargePerDEMean->SetBinError(iDE, tmp->GetMeanError());
653 hClusterChargePerDESigma->SetBinContent(iDE, tmp->GetRMS());
654 hClusterChargePerDESigma->SetBinError(iDE, tmp->GetRMSError());
658 tmp = hClusterSizePerDE->ProjectionY("tmp",iDE,iDE,"e");
659 if (tmp->GetEntries() > 10.) {
660 hClusterSizePerDEMean->SetBinContent(iDE, tmp->GetMean());
661 hClusterSizePerDEMean->SetBinError(iDE, tmp->GetMeanError());
662 hClusterSizePerDESigma->SetBinContent(iDE, tmp->GetRMS());
663 hClusterSizePerDESigma->SetBinError(iDE, tmp->GetRMSError());
669 // Post summary data.
670 PostData(5, fListNorm);
673 //________________________________________________________________________
674 Double_t AliAnalysisTaskMuonQA::ChangeThetaRange(Double_t theta)
676 /// set theta range from -180 to +180 degrees
677 if(theta < -2.5) return (theta / TMath::Pi() + 1.) * 180.;
678 else if(theta > 2.5) return (theta / TMath::Pi() - 1.) * 180.;
679 else return theta / TMath::Pi() * 180.;
682 //________________________________________________________________________
683 UInt_t AliAnalysisTaskMuonQA::BuildTriggerWord(TString& FiredTriggerClasses)
685 /// build the trigger word from the fired trigger classes and the list of selectable trigger
689 TObjString* trigClasseName = 0x0;
690 TIter nextTrigger(fSelectTriggerClass);
691 while ((trigClasseName = static_cast<TObjString*>(nextTrigger()))) {
693 TRegexp GenericTriggerClasseName(trigClasseName->String());
694 if (FiredTriggerClasses.Contains(GenericTriggerClasseName)) word |= trigClasseName->GetUniqueID();
701 //________________________________________________________________________
702 TList* AliAnalysisTaskMuonQA::BuildListOfTriggerCases(TString& FiredTriggerClasses)
704 /// build the list of trigger for the counters from the fired trigger classes and the list of trigger classes
705 /// returned TList must be deleted by user
707 TList* list = new TList();
709 Bool_t foundCINT1B = kFALSE;
710 Bool_t foundCMUS1B = kFALSE;
713 list->AddLast(new TObjString("trigger:any"));
715 TObjString* trigClasseName = 0x0;
716 TIter nextTrigger(fTriggerClass);
717 while ((trigClasseName = static_cast<TObjString*>(nextTrigger()))) {
719 TRegexp GenericTriggerClasseName(trigClasseName->String());
720 if (FiredTriggerClasses.Contains(GenericTriggerClasseName)) {
722 // add specific trigger case
723 TObjString* trigShortName = static_cast<TObjString*>(fTriggerClass->GetValue(trigClasseName));
724 list->AddLast(new TObjString(Form("trigger:%s",trigShortName->GetName())));
726 // check for CINT1B and CMUS1B trigger
727 if (trigShortName->String() == "CINT1B") foundCINT1B = kTRUE;
728 else if (trigShortName->String() == "CMUS1B") foundCMUS1B = kTRUE;
734 // add the special case CINT1B+CMUS1B
735 if (foundCINT1B && foundCMUS1B) list->AddLast(new TObjString("trigger:CINT1B+CMUS1B"));
737 // add case other if no specific trigger was found
738 if (list->GetSize() == 1) list->AddLast(new TObjString("trigger:other"));