]>
Commit | Line | Data |
---|---|---|
94ef1a28 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | #include <Riostream.h> | |
17 | ||
18 | // ROOT includes | |
19 | #include "TH1F.h" | |
20 | #include "TH2F.h" | |
21 | #include "TCanvas.h" | |
22 | #include "TROOT.h" | |
23 | #include "TString.h" | |
24 | #include "TObjArray.h" | |
25 | #include "TMath.h" | |
26 | #include "TFile.h" | |
03ac5989 | 27 | #include "TRegexp.h" |
28 | #include "TMap.h" | |
29 | #include "TList.h" | |
30 | #include "TObjString.h" | |
94ef1a28 | 31 | |
32 | // STEER includes | |
33 | #include "AliESDEvent.h" | |
34 | #include "AliESDMuonTrack.h" | |
35 | #include "AliESDMuonCluster.h" | |
36 | #include "AliESDInputHandler.h" | |
37 | ||
38 | // ANALYSIS includes | |
39 | #include "AliAnalysisTaskSE.h" | |
40 | #include "AliAnalysisDataSlot.h" | |
41 | #include "AliAnalysisManager.h" | |
42 | #include "AliAnalysisTaskMuonQA.h" | |
43 | #include "AliCounterCollection.h" | |
44 | ||
45 | ClassImp(AliAnalysisTaskMuonQA) | |
46 | ||
47 | const Int_t AliAnalysisTaskMuonQA::nCh = 10; | |
48 | ||
49 | const Int_t AliAnalysisTaskMuonQA::nDE = 1100; | |
50 | ||
51 | const Float_t AliAnalysisTaskMuonQA::dMax[5] = {176.6, 229.0, 308.84, 418.2, 522.0}; // cm | |
52 | ||
40be9f05 | 53 | //________________________________________________________________________ |
54 | AliAnalysisTaskMuonQA::AliAnalysisTaskMuonQA() : | |
55 | AliAnalysisTaskSE(), | |
56 | fList(0x0), | |
57 | fListExpert(0x0), | |
58 | fListNorm(0x0), | |
59 | fTrackCounters(0x0), | |
60 | fEventCounters(0x0), | |
61 | fSelectCharge(0), | |
b4f7418a | 62 | fSelectPhysics(kFALSE), |
03ac5989 | 63 | fSelectTrigger(kFALSE), |
64 | fTriggerMask(0), | |
65 | fTriggerClass(0x0), | |
66 | fSelectTriggerClass(0x0) | |
40be9f05 | 67 | { |
68 | // Dummy constructor | |
69 | } | |
70 | ||
94ef1a28 | 71 | //________________________________________________________________________ |
72 | AliAnalysisTaskMuonQA::AliAnalysisTaskMuonQA(const char *name) : | |
73 | AliAnalysisTaskSE(name), | |
74 | fList(0x0), | |
75 | fListExpert(0x0), | |
40be9f05 | 76 | fListNorm(0x0), |
94ef1a28 | 77 | fTrackCounters(0x0), |
78 | fEventCounters(0x0), | |
79 | fSelectCharge(0), | |
b4f7418a | 80 | fSelectPhysics(kFALSE), |
03ac5989 | 81 | fSelectTrigger(kFALSE), |
82 | fTriggerMask(0), | |
83 | fTriggerClass(0x0), | |
84 | fSelectTriggerClass(0x0) | |
94ef1a28 | 85 | { |
86 | /// Constructor | |
87 | ||
88 | // Output slot #1 writes into a TObjArray container | |
89 | DefineOutput(1,TObjArray::Class()); | |
90 | // Output slot #2 writes into a TObjArray container | |
91 | DefineOutput(2,TObjArray::Class()); | |
92 | // Output slot #3 writes track counters | |
93 | DefineOutput(3,AliCounterCollection::Class()); | |
94 | // Output slot #4 writes event counters | |
95 | DefineOutput(4,AliCounterCollection::Class()); | |
40be9f05 | 96 | // Output slot #5 writes normalized histograms |
97 | DefineOutput(5,TObjArray::Class()); | |
94ef1a28 | 98 | } |
99 | ||
100 | //________________________________________________________________________ | |
101 | AliAnalysisTaskMuonQA::~AliAnalysisTaskMuonQA() | |
102 | { | |
103 | /// Destructor | |
104 | delete fList; | |
105 | delete fListExpert; | |
40be9f05 | 106 | delete fListNorm; |
94ef1a28 | 107 | delete fTrackCounters; |
108 | delete fEventCounters; | |
03ac5989 | 109 | delete fTriggerClass; |
110 | delete fSelectTriggerClass; | |
94ef1a28 | 111 | } |
112 | ||
113 | //___________________________________________________________________________ | |
114 | void AliAnalysisTaskMuonQA::UserCreateOutputObjects() | |
115 | { | |
116 | /// Create histograms and counters | |
117 | ||
03ac5989 | 118 | // set the list of trigger classes with corresponding short names |
119 | fTriggerClass = new TMap(20); | |
120 | fTriggerClass->SetOwnerKeyValue(); | |
121 | fTriggerClass->Add(new TObjString(" CBEAMB"), new TObjString("CBEAMB")); | |
122 | fTriggerClass->Add(new TObjString(" CINT1B-ABCE-NOPF-ALL "), new TObjString("CINT1B")); | |
123 | fTriggerClass->Add(new TObjString(" CMUS1B-ABCE-NOPF-MUON "), new TObjString("CMUS1B")); | |
124 | fTriggerClass->Add(new TObjString(" CINT1B-ABCE-NOPF-ALL CMUS1B-ABCE-NOPF-MUON "), new TObjString("CINT1B+CMUS1B")); | |
125 | fTriggerClass->Add(new TObjString(" CINT1[AC]-"), new TObjString("CINT1AC")); | |
126 | fTriggerClass->Add(new TObjString(" CINT1-E-"), new TObjString("CINT1E")); | |
127 | fTriggerClass->Add(new TObjString(" CMUS1[AC]-"), new TObjString("CMUS1AC")); | |
128 | fTriggerClass->Add(new TObjString(" CMUS1-E-"), new TObjString("CMUS1E")); | |
129 | fTriggerClass->Add(new TObjString(" CINT1-B-"), new TObjString("CINT1B")); | |
130 | fTriggerClass->Add(new TObjString(" CMUS1-B-"), new TObjString("CMUS1B")); | |
131 | fTriggerClass->Add(new TObjString(" CINT1-AC-"), new TObjString("CINT1AC")); | |
132 | fTriggerClass->Add(new TObjString(" CMUS1-AC-"), new TObjString("CMUS1AC")); | |
133 | fTriggerClass->Add(new TObjString(" CSH1-B-"), new TObjString("CSH1B")); | |
134 | ||
135 | // set the corresponding list of trigger key words for counters | |
136 | TString triggerKeys = "CBEAMB/CINT1B/CMUS1B/CINT1B+CMUS1B/CINT1AC/CINT1E/CMUS1AC/CMUS1E/CSH1B/other/any"; | |
137 | ||
138 | // set the list of trigger classes that can be selected to fill histograms (in case the physics selection is not used) | |
139 | fSelectTriggerClass = new TList(); | |
140 | fSelectTriggerClass->SetOwner(); | |
141 | fSelectTriggerClass->AddLast(new TObjString(" CINT1B-ABCE-NOPF-ALL ")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB); | |
142 | fSelectTriggerClass->AddLast(new TObjString(" CMUS1B-ABCE-NOPF-MUON ")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUON); | |
143 | fSelectTriggerClass->AddLast(new TObjString(" CINT1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB); | |
144 | fSelectTriggerClass->AddLast(new TObjString(" CMUS1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUON); | |
145 | fSelectTriggerClass->AddLast(new TObjString(" CSH1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kHighMult); | |
146 | ||
147 | // create histograms | |
94ef1a28 | 148 | fList = new TObjArray(2000); |
149 | fList->SetOwner(); | |
150 | fListExpert = new TObjArray(2000); | |
151 | fListExpert->SetOwner(); | |
152 | ||
153 | // track info | |
154 | TH1F* hNTracks = new TH1F("hNTracks", "number of tracks;n_{tracks}", 20, 0., 20.); | |
155 | fList->AddAtAndExpand(hNTracks, kNTracks); | |
156 | ||
157 | TH1F* hMatchTrig = new TH1F("hMatchTrig", "number of tracks matched with trigger;n_{tracks}", 20, 0., 20.); | |
158 | fList->AddAtAndExpand(hMatchTrig, kMatchTrig); | |
159 | ||
160 | TH1F* hSign = new TH1F("hSign", "track sign;sign", 3, -1.5, 1.5); | |
161 | fList->AddAtAndExpand(hSign, kSign); | |
162 | ||
163 | TH1F* hDCA = new TH1F("hDCA", "DCA distribution;DCA (cm)", 500, 0., 500.); | |
164 | fList->AddAtAndExpand(hDCA, kDCA); | |
165 | ||
166 | TH1F* hP = new TH1F("hP", "momentum distribution;p (GeV/c)", 300, 0., 300.); | |
167 | fList->AddAtAndExpand(hP, kP); | |
168 | ||
03ac5989 | 169 | TH1F* hPMuPlus = new TH1F("hPMuPlus", "momentum distribution of #mu^{+};p (GeV/c)", 300, 0., 300.); |
170 | fList->AddAtAndExpand(hPMuPlus, kPMuPlus); | |
171 | ||
172 | TH1F* hPMuMinus = new TH1F("hPMuMinus", "momentum distribution of #mu^{-};p (GeV/c)", 300, 0., 300.); | |
173 | fList->AddAtAndExpand(hPMuMinus, kPMuMinus); | |
174 | ||
94ef1a28 | 175 | TH1F* hPt = new TH1F("hPt", "transverse momentum distribution;p_{t} (GeV/c)", 300, 0., 30); |
176 | fList->AddAtAndExpand(hPt, kPt); | |
177 | ||
03ac5989 | 178 | TH1F* hPtMuPlus = new TH1F("hPtMuPlus", "transverse momentum distribution of #mu^{+};p_{t} (GeV/c)", 300, 0., 30); |
179 | fList->AddAtAndExpand(hPtMuPlus, kPtMuPlus); | |
180 | ||
181 | TH1F* hPtMuMinus = new TH1F("hPtMuMinus", "transverse momentum distribution of #mu^{-};p_{t} (GeV/c)", 300, 0., 30); | |
182 | fList->AddAtAndExpand(hPtMuMinus, kPtMuMinus); | |
183 | ||
94ef1a28 | 184 | TH1F* hRapidity = new TH1F("hRapidity", "rapidity distribution;rapidity", 200, -4.5, -2.); |
185 | fList->AddAtAndExpand(hRapidity, kRapidity); | |
186 | ||
187 | TH1F* hThetaX = new TH1F("hThetaX", "#theta_{X} distribution;#theta_{X} (degree)", 360, -180., 180); | |
188 | fList->AddAtAndExpand(hThetaX, kThetaX); | |
189 | ||
190 | TH1F* hThetaY = new TH1F("hThetaY", "#theta_{Y} distribution;#theta_{Y} (degree)", 360, -180., 180); | |
191 | fList->AddAtAndExpand(hThetaY, kThetaY); | |
192 | ||
193 | TH1F* hChi2 = new TH1F("hChi2", "normalized #chi^{2} distribution;#chi^{2} / ndf", 500, 0., 50.); | |
194 | fList->AddAtAndExpand(hChi2, kChi2); | |
195 | ||
196 | TH1F* hProbChi2 = new TH1F("hProbChi2", "distribution of probability of #chi^{2};prob(#chi^{2})", 100, 0., 1.); | |
197 | fList->AddAtAndExpand(hProbChi2, kProbChi2); | |
198 | ||
199 | // cluster info | |
200 | TH1F* hNClustersPerTrack = new TH1F("hNClustersPerTrack", "number of associated clusters per track;n_{clusters}", 20, 0., 20.); | |
201 | fList->AddAtAndExpand(hNClustersPerTrack, kNClustersPerTrack); | |
202 | ||
203 | TH1F* hNChamberHitPerTrack = new TH1F("hNChamberHitPerTrack", "number of chambers hit per track;n_{chamber hit}", 15, 0., 15.); | |
204 | fList->AddAtAndExpand(hNChamberHitPerTrack, kNChamberHitPerTrack); | |
205 | ||
206 | TH1F* hNClustersPerCh = new TH1F("hNClustersPerCh", "averaged number of clusters per chamber per track;chamber ID;<n_{clusters}>", nCh, -0.5, nCh-0.5); | |
207 | hNClustersPerCh->Sumw2(); | |
208 | hNClustersPerCh->SetOption("P"); | |
209 | hNClustersPerCh->SetMarkerStyle(kFullDotMedium); | |
210 | hNClustersPerCh->SetMarkerColor(kBlue); | |
40be9f05 | 211 | fListExpert->AddAtAndExpand(hNClustersPerCh, kNClustersPerCh); |
94ef1a28 | 212 | |
213 | TH1F* hNClustersPerDE = new TH1F("hNClustersPerDE", "averaged number of clusters per DE per track;DetElem ID;<n_{clusters}>", nDE+1, -0.5, nDE+0.5); | |
214 | hNClustersPerDE->Sumw2(); | |
215 | hNClustersPerDE->SetOption("P"); | |
216 | hNClustersPerDE->SetMarkerStyle(kFullDotMedium); | |
217 | hNClustersPerDE->SetMarkerColor(kBlue); | |
40be9f05 | 218 | fListExpert->AddAtAndExpand(hNClustersPerDE, kNClustersPerDE); |
94ef1a28 | 219 | |
220 | for (Int_t i = 0; i < nCh; i++) { | |
221 | Float_t rMax = 0.5*dMax[i/2]; | |
222 | TH2F* hClusterHitMapInCh = new TH2F(Form("hClusterHitMapInCh%d",i+1), Form("cluster position distribution in chamber %d;X (cm);Y (cm)",i+1), | |
223 | 100, -rMax, rMax, 100, -rMax, rMax); | |
224 | fListExpert->AddAtAndExpand(hClusterHitMapInCh, kClusterHitMapInCh+i); | |
225 | ||
226 | TH1F* hClusterChargeInCh = new TH1F(Form("hClusterChargeInCh%d",i+1), Form("cluster charge distribution in chamber %d;charge (fC)",i+1), 100, 0., 1000.); | |
227 | fListExpert->AddAtAndExpand(hClusterChargeInCh, kClusterChargeInCh+i); | |
228 | ||
229 | TH1F* hClusterSizeInCh = new TH1F(Form("hClusterSizeInCh%d",i+1), Form("cluster size distribution in chamber %d;size (n_{pads})",i+1), 200, 0., 200.); | |
230 | fListExpert->AddAtAndExpand(hClusterSizeInCh, kClusterSizeInCh+i); | |
231 | } | |
232 | ||
233 | TH2F* hClusterChargePerDE = new TH2F("hClusterChargePerDE", "cluster charge distribution per DE;DetElem ID;charge (fC)", nDE+1, -0.5, nDE+0.5, 100, 0., 1000.); | |
234 | fListExpert->AddAtAndExpand(hClusterChargePerDE, kClusterChargePerDE); | |
235 | ||
236 | 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.); | |
237 | fListExpert->AddAtAndExpand(hClusterSizePerDE, kClusterSizePerDE); | |
238 | ||
94ef1a28 | 239 | // initialize track counters |
240 | fTrackCounters = new AliCounterCollection("trackCounters"); | |
03ac5989 | 241 | fTrackCounters->AddRubric("track", "trackeronly/triggeronly/matched"); |
242 | fTrackCounters->AddRubric("trigger", triggerKeys.Data()); | |
94ef1a28 | 243 | fTrackCounters->AddRubric("run", 1000000); |
244 | fTrackCounters->AddRubric("selected", "yes/no"); | |
245 | fTrackCounters->AddRubric("triggerRO", "good/bad"); | |
03ac5989 | 246 | fTrackCounters->AddRubric("charge", "pos/neg/any"); |
247 | fTrackCounters->AddRubric("pt", "low/high/any"); | |
94ef1a28 | 248 | fTrackCounters->Init(); |
249 | ||
250 | // initialize event counters | |
251 | fEventCounters = new AliCounterCollection("eventCounters"); | |
252 | fEventCounters->AddRubric("event", "muon/any"); | |
03ac5989 | 253 | fEventCounters->AddRubric("trigger", triggerKeys.Data()); |
94ef1a28 | 254 | fEventCounters->AddRubric("run", 1000000); |
255 | fEventCounters->AddRubric("selected", "yes/no"); | |
256 | fEventCounters->AddRubric("triggerRO", "good/bad"); | |
257 | fEventCounters->Init(); | |
258 | ||
259 | // Post data at least once per task to ensure data synchronisation (required for merging) | |
260 | PostData(1, fList); | |
261 | PostData(2, fListExpert); | |
262 | PostData(3, fTrackCounters); | |
263 | PostData(4, fEventCounters); | |
264 | } | |
265 | ||
266 | //________________________________________________________________________ | |
267 | void AliAnalysisTaskMuonQA::UserExec(Option_t *) | |
268 | { | |
269 | /// Called for each event | |
270 | ||
94ef1a28 | 271 | AliESDEvent* fESD = dynamic_cast<AliESDEvent*>(InputEvent()); |
272 | if (!fESD) { | |
273 | Printf("ERROR: fESD not available"); | |
274 | return; | |
275 | } | |
276 | ||
03ac5989 | 277 | // check physics selection |
278 | UInt_t triggerWord = (fInputHandler) ? fInputHandler->IsEventSelected() : 0; | |
279 | Bool_t isPhysicsSelected = (triggerWord != 0); | |
280 | TString selected = isPhysicsSelected ? "selected:yes" : "selected:no"; | |
b4f7418a | 281 | |
03ac5989 | 282 | // check trigger selection |
283 | TString FiredTriggerClasses = fESD->GetFiredTriggerClasses(); | |
284 | if (!fSelectPhysics) triggerWord = BuildTriggerWord(FiredTriggerClasses); | |
285 | Bool_t isTriggerSelected = ((triggerWord & fTriggerMask) != 0); | |
286 | ||
287 | // first loop over tracks to check for trigger readout problem | |
288 | Int_t nTracks = (Int_t) fESD->GetNumberOfMuonTracks(); | |
94ef1a28 | 289 | Int_t nTriggerTracks = 0; |
03ac5989 | 290 | for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack) |
291 | if (fESD->GetMuonTrack(iTrack)->ContainTriggerData()) nTriggerTracks++; | |
292 | TString triggerRO = (nTriggerTracks < 10) ? "triggerRO:good" : "triggerRO:bad"; | |
94ef1a28 | 293 | |
03ac5989 | 294 | // --- fill event counters --- |
295 | ||
296 | // build the list of trigger cases | |
297 | TList* triggerCases = BuildListOfTriggerCases(FiredTriggerClasses); | |
298 | ||
299 | // loop over trigger cases | |
300 | TObjString* triggerKey = 0x0; | |
301 | TIter nextTriggerCase(triggerCases); | |
302 | while ((triggerKey = static_cast<TObjString*>(nextTriggerCase()))) { | |
94ef1a28 | 303 | |
03ac5989 | 304 | // any event |
305 | fEventCounters->Count(Form("event:any/%s/run:%d/%s/%s", triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data())); | |
94ef1a28 | 306 | |
03ac5989 | 307 | // muon event |
308 | if (nTracks > 0) fEventCounters->Count(Form("event:muon/%s/run:%d/%s/%s", triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data())); | |
309 | ||
310 | } | |
311 | ||
312 | // second loop over tracks to fill histograms and track counters | |
313 | Int_t nSelectedTrackerTracks = 0; | |
314 | Int_t nSelectedTrackMatchTrig = 0; | |
315 | Int_t nPVTracks = fESD->GetPrimaryVertex()->GetNContributors(); | |
316 | for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack) { | |
317 | ||
318 | // get the ESD track | |
94ef1a28 | 319 | AliESDMuonTrack* esdTrack = fESD->GetMuonTrack(iTrack); |
94ef1a28 | 320 | |
03ac5989 | 321 | // --- fill track counters --- |
322 | ||
323 | // define the key words | |
324 | TString trackKey = "track:"; | |
325 | TString chargeKey = "charge:"; | |
326 | Bool_t lowPt = kFALSE; | |
327 | Bool_t highPt = kFALSE; | |
328 | if (esdTrack->ContainTrackerData()) { | |
329 | ||
330 | if (esdTrack->ContainTriggerData()) trackKey += "matched"; | |
331 | else trackKey += "trackeronly"; | |
332 | ||
333 | Short_t trackCharge = esdTrack->Charge(); | |
334 | if (trackCharge < 0) chargeKey += "neg"; | |
335 | else chargeKey += "pos"; | |
336 | ||
337 | Double_t thetaTrackAbsEnd = TMath::ATan(esdTrack->GetRAtAbsorberEnd()/505.) * TMath::RadToDeg(); | |
338 | Double_t trackPt = esdTrack->Pt(); | |
339 | if (trackPt > 1. && nPVTracks>0 && thetaTrackAbsEnd>2. ) lowPt = kTRUE; | |
340 | if (trackPt > 2. && nPVTracks>0 && thetaTrackAbsEnd>2. ) highPt = kTRUE; | |
341 | ||
342 | } else { | |
343 | ||
344 | trackKey += "triggeronly"; | |
345 | chargeKey = ""; | |
346 | ||
347 | } | |
94ef1a28 | 348 | |
03ac5989 | 349 | // loop over trigger cases and fill counters |
350 | nextTriggerCase.Reset(); | |
351 | while ((triggerKey = static_cast<TObjString*>(nextTriggerCase()))) { | |
352 | ||
353 | // any charge / any pt | |
354 | fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/charge:any/pt:any", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data())); | |
355 | ||
356 | // any charge / specific pt | |
357 | if (lowPt) fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/charge:any/pt:low", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data())); | |
358 | if (highPt) fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/charge:any/pt:high", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data())); | |
359 | ||
360 | if (!chargeKey.IsNull()) { | |
361 | ||
362 | // specific charge / any pt | |
363 | fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/%s/pt:any", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), chargeKey.Data())); | |
364 | ||
365 | // specific charge / specific pt | |
366 | if (lowPt) fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/%s/pt:low", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), chargeKey.Data())); | |
367 | if (highPt) fTrackCounters->Count(Form("%s/%s/run:%d/%s/%s/%s/pt:high", trackKey.Data(), triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), chargeKey.Data())); | |
368 | ||
369 | } | |
370 | ||
94ef1a28 | 371 | } |
372 | ||
373 | // --- apply selections and fill histograms with selected tracks --- | |
374 | ||
03ac5989 | 375 | // remove "ghost" |
376 | if (!esdTrack->ContainTrackerData()) continue; | |
377 | ||
94ef1a28 | 378 | // select on "physics" before filling histograms |
379 | if (fSelectPhysics && !isPhysicsSelected) continue; | |
380 | ||
03ac5989 | 381 | // select on trigger before filling histograms |
382 | if (fSelectTrigger && !isTriggerSelected) continue; | |
b4f7418a | 383 | |
94ef1a28 | 384 | // select on track charge |
385 | if (fSelectCharge*esdTrack->Charge() < 0) continue; | |
386 | ||
387 | nSelectedTrackerTracks++; | |
388 | if (esdTrack->ContainTriggerData()) nSelectedTrackMatchTrig++; | |
389 | ||
03ac5989 | 390 | Double_t trackP = esdTrack->P(); |
391 | Double_t trackPt = esdTrack->Pt(); | |
392 | Short_t trackCharge = esdTrack->Charge(); | |
393 | ((TH1F*)fList->UncheckedAt(kP))->Fill(trackP); | |
394 | ((TH1F*)fList->UncheckedAt(kPt))->Fill(trackPt); | |
395 | if (trackCharge < 0) { | |
396 | ((TH1F*)fList->UncheckedAt(kPMuMinus))->Fill(trackP); | |
397 | ((TH1F*)fList->UncheckedAt(kPtMuMinus))->Fill(trackPt); | |
398 | } else { | |
399 | ((TH1F*)fList->UncheckedAt(kPMuPlus))->Fill(trackP); | |
400 | ((TH1F*)fList->UncheckedAt(kPtMuPlus))->Fill(trackPt); | |
401 | } | |
94ef1a28 | 402 | ((TH1F*)fList->UncheckedAt(kRapidity))->Fill(esdTrack->Y()); |
403 | Int_t ndf = 2 * esdTrack->GetNHit() - 5; | |
404 | ((TH1F*)fList->UncheckedAt(kChi2))->Fill(esdTrack->GetChi2()/ndf); | |
405 | ((TH1F*)fList->UncheckedAt(kProbChi2))->Fill(TMath::Prob(esdTrack->GetChi2(),ndf)); | |
406 | ((TH1F*)fList->UncheckedAt(kThetaX))->Fill(ChangeThetaRange(esdTrack->GetThetaXUncorrected())); | |
407 | ((TH1F*)fList->UncheckedAt(kThetaY))->Fill(ChangeThetaRange(esdTrack->GetThetaYUncorrected())); | |
408 | ((TH1F*)fList->UncheckedAt(kNClustersPerTrack))->Fill(esdTrack->GetNHit()); | |
03ac5989 | 409 | ((TH1F*)fList->UncheckedAt(kSign))->Fill(trackCharge); |
94ef1a28 | 410 | ((TH1F*)fList->UncheckedAt(kDCA))->Fill(esdTrack->GetDCA()); |
411 | ||
412 | Int_t nChamberHit = 0; | |
413 | for (Int_t ich=0; ich<10; ich++) if (esdTrack->IsInMuonClusterMap(ich)) nChamberHit++; | |
414 | ((TH1F*)fList->UncheckedAt(kNChamberHitPerTrack))->Fill(nChamberHit); | |
415 | ||
416 | // what follows concern clusters | |
417 | if(!esdTrack->ClustersStored()) continue; | |
418 | ||
419 | AliESDMuonCluster *esdCluster = (AliESDMuonCluster*) esdTrack->GetClusters().First(); | |
420 | while (esdCluster) { | |
421 | ||
422 | Int_t chId = esdCluster->GetChamberId(); | |
423 | Int_t deId = esdCluster->GetDetElemId(); | |
424 | ||
40be9f05 | 425 | ((TH1F*)fListExpert->UncheckedAt(kNClustersPerCh))->Fill(chId); |
426 | ((TH1F*)fListExpert->UncheckedAt(kNClustersPerDE))->Fill(deId); | |
94ef1a28 | 427 | |
428 | ((TH1F*)fListExpert->UncheckedAt(kClusterHitMapInCh+chId))->Fill(esdCluster->GetX(), esdCluster->GetY()); | |
429 | ||
430 | ((TH1F*)fListExpert->UncheckedAt(kClusterChargeInCh+chId))->Fill(esdCluster->GetCharge()); | |
431 | ((TH1F*)fListExpert->UncheckedAt(kClusterChargePerDE))->Fill(deId, esdCluster->GetCharge()); | |
432 | ||
433 | if (esdCluster->PadsStored()) { // discard clusters with pad not stored in ESD | |
434 | ((TH1F*)fListExpert->UncheckedAt(kClusterSizeInCh+chId))->Fill(esdCluster->GetNPads()); | |
435 | ((TH1F*)fListExpert->UncheckedAt(kClusterSizePerDE))->Fill(deId, esdCluster->GetNPads()); | |
436 | } | |
437 | ||
438 | esdCluster = (AliESDMuonCluster*) esdTrack->GetClusters().After(esdCluster); | |
439 | } | |
440 | ||
441 | } | |
442 | ||
03ac5989 | 443 | if ((!fSelectPhysics || isPhysicsSelected) && (!fSelectTrigger || isTriggerSelected)) { |
b4f7418a | 444 | ((TH1F*)fList->UncheckedAt(kNTracks))->Fill(nSelectedTrackerTracks); |
445 | ((TH1F*)fList->UncheckedAt(kMatchTrig))->Fill(nSelectedTrackMatchTrig); | |
446 | } | |
94ef1a28 | 447 | |
03ac5989 | 448 | // clean memory |
449 | delete triggerCases; | |
94ef1a28 | 450 | |
451 | // Post final data. It will be written to a file with option "RECREATE" | |
452 | PostData(1, fList); | |
453 | PostData(2, fListExpert); | |
454 | PostData(3, fTrackCounters); | |
455 | PostData(4, fEventCounters); | |
456 | } | |
457 | ||
458 | //________________________________________________________________________ | |
459 | void AliAnalysisTaskMuonQA::Terminate(Option_t *) | |
460 | { | |
461 | /// Normalize histograms | |
462 | /// Draw result to the screen | |
463 | /// Print statistics | |
464 | ||
94ef1a28 | 465 | // global statistic |
40be9f05 | 466 | fTrackCounters = static_cast<AliCounterCollection*>(GetOutputData(3)); |
467 | fEventCounters = static_cast<AliCounterCollection*>(GetOutputData(4)); | |
94ef1a28 | 468 | if (fTrackCounters && fEventCounters) { |
469 | if (!gROOT->IsBatch()) { | |
470 | cout<<"whole statistics without selection:"<<endl; | |
471 | fEventCounters->Print("trigger/event"); | |
472 | fTrackCounters->Print("trigger/track"); | |
473 | cout<<"whole statistics of selected events:"<<endl; | |
474 | fEventCounters->Print("trigger/event","selected:yes"); | |
475 | fTrackCounters->Print("trigger/track","selected:yes"); | |
476 | new TCanvas(); | |
477 | fEventCounters->Draw("event","trigger",""); | |
478 | new TCanvas(); | |
479 | fTrackCounters->Draw("track","trigger",""); | |
480 | new TCanvas(); | |
481 | fEventCounters->Draw("event","trigger","selected:yes"); | |
482 | new TCanvas(); | |
483 | fTrackCounters->Draw("track","trigger","selected:yes"); | |
484 | } | |
485 | } | |
486 | ||
40be9f05 | 487 | // recover output histograms |
488 | fList = static_cast<TObjArray*>(GetOutputData(1)); | |
489 | fListExpert = static_cast<TObjArray*>(GetOutputData(2)); | |
490 | if (!fList || !fListExpert) return; | |
491 | ||
492 | // create summary plots | |
493 | fListNorm = new TObjArray(1000); | |
494 | fListNorm->SetOwner(); | |
495 | ||
496 | // mean/dispersion of cluster charge per chamber/DE | |
497 | TH1F* hClusterChargePerChMean = new TH1F("hClusterChargePerChMean", "cluster mean charge per chamber;chamber ID;<charge> (fC)", nCh, -0.5, nCh-0.5); | |
498 | hClusterChargePerChMean->SetOption("P"); | |
499 | hClusterChargePerChMean->SetMarkerStyle(kFullDotMedium); | |
500 | hClusterChargePerChMean->SetMarkerColor(kBlue); | |
501 | fListNorm->AddAtAndExpand(hClusterChargePerChMean, kClusterChargePerChMean); | |
502 | ||
503 | TH1F* hClusterChargePerChSigma = new TH1F("hClusterChargePerChSigma", "cluster charge dispersion per chamber;chamber ID;#sigma_{charge} (fC)", nCh, -0.5, nCh-0.5); | |
504 | hClusterChargePerChSigma->SetOption("P"); | |
505 | hClusterChargePerChSigma->SetMarkerStyle(kFullDotMedium); | |
506 | hClusterChargePerChSigma->SetMarkerColor(kBlue); | |
507 | fListNorm->AddAtAndExpand(hClusterChargePerChSigma, kClusterChargePerChSigma); | |
508 | ||
509 | TH1F* hClusterChargePerDEMean = new TH1F("hClusterChargePerDEMean", "cluster mean charge per DE;DetElem ID;<charge> (fC)", nDE+1, -0.5, nDE+0.5); | |
510 | hClusterChargePerDEMean->SetOption("P"); | |
511 | hClusterChargePerDEMean->SetMarkerStyle(kFullDotMedium); | |
512 | hClusterChargePerDEMean->SetMarkerColor(kBlue); | |
513 | fListNorm->AddAtAndExpand(hClusterChargePerDEMean, kClusterChargePerDEMean); | |
514 | ||
515 | TH1F* hClusterChargePerDESigma = new TH1F("hClusterChargePerDESigma", "cluster charge dispersion per DE;DetElem ID;#sigma_{charge} (fC)", nDE+1, -0.5, nDE+0.5); | |
516 | hClusterChargePerDESigma->SetOption("P"); | |
517 | hClusterChargePerDESigma->SetMarkerStyle(kFullDotMedium); | |
518 | hClusterChargePerDESigma->SetMarkerColor(kBlue); | |
519 | fListNorm->AddAtAndExpand(hClusterChargePerDESigma, kClusterChargePerDESigma); | |
520 | ||
521 | // mean/dispersion of cluster size per chamber/DE | |
522 | TH1F* hClusterSizePerChMean = new TH1F("hClusterSizePerChMean", "cluster mean size per chamber;chamber ID;<size> (n_{pads})", nCh, -0.5, nCh-0.5); | |
523 | hClusterSizePerChMean->SetOption("P"); | |
524 | hClusterSizePerChMean->SetMarkerStyle(kFullDotMedium); | |
525 | hClusterSizePerChMean->SetMarkerColor(kBlue); | |
526 | fListNorm->AddAtAndExpand(hClusterSizePerChMean, kClusterSizePerChMean); | |
527 | ||
528 | TH1F* hClusterSizePerChSigma = new TH1F("hClusterSizePerChSigma", "cluster size dispersion per chamber;chamber ID;#sigma_{size} (n_{pads})", nCh, -0.5, nCh-0.5); | |
529 | hClusterSizePerChSigma->SetOption("P"); | |
530 | hClusterSizePerChSigma->SetMarkerStyle(kFullDotMedium); | |
531 | hClusterSizePerChSigma->SetMarkerColor(kBlue); | |
532 | fListNorm->AddAtAndExpand(hClusterSizePerChSigma, kClusterSizePerChSigma); | |
533 | ||
534 | TH1F* hClusterSizePerDEMean = new TH1F("hClusterSizePerDEMean", "cluster mean size per DE;DetElem ID;<size> (n_{pads})", nDE+1, -0.5, nDE+0.5); | |
535 | hClusterSizePerDEMean->SetOption("P"); | |
536 | hClusterSizePerDEMean->SetMarkerStyle(kFullDotMedium); | |
537 | hClusterSizePerDEMean->SetMarkerColor(kBlue); | |
538 | fListNorm->AddAtAndExpand(hClusterSizePerDEMean, kClusterSizePerDEMean); | |
539 | ||
540 | TH1F* hClusterSizePerDESigma = new TH1F("hClusterSizePerDESigma", "cluster size dispersion per DE;DetElem ID;#sigma_{size} (n_{pads})", nDE+1, -0.5, nDE+0.5); | |
541 | hClusterSizePerDESigma->SetOption("P"); | |
542 | hClusterSizePerDESigma->SetMarkerStyle(kFullDotMedium); | |
543 | hClusterSizePerDESigma->SetMarkerColor(kBlue); | |
544 | fListNorm->AddAtAndExpand(hClusterSizePerDESigma, kClusterSizePerDESigma); | |
545 | ||
546 | // normalize histograms | |
94ef1a28 | 547 | Float_t nTracks = ((TH1F*)fList->UncheckedAt(kNClustersPerTrack))->GetEntries(); |
548 | if (nTracks > 0.) { | |
40be9f05 | 549 | ((TH1F*)fListExpert->UncheckedAt(kNClustersPerCh))->Scale(1./nTracks); |
550 | ((TH1F*)fListExpert->UncheckedAt(kNClustersPerDE))->Scale(1./nTracks); | |
03ac5989 | 551 | fListNorm->AddAtAndExpand(((TH1F*)fListExpert->UncheckedAt(kNClustersPerCh))->Clone(), kNClustersPerChPerTrack); |
552 | fListNorm->AddAtAndExpand(((TH1F*)fListExpert->UncheckedAt(kNClustersPerDE))->Clone(), kNClustersPerDEPerTrack); | |
94ef1a28 | 553 | } |
554 | ||
555 | // fill summary plots per chamber | |
94ef1a28 | 556 | for (Int_t iCh = 0; iCh < nCh; iCh++) { |
557 | ||
558 | TH1* hClusterChargeInCh = ((TH1F*)fListExpert->UncheckedAt(kClusterChargeInCh+iCh)); | |
559 | hClusterChargePerChMean->SetBinContent(iCh+1, hClusterChargeInCh->GetMean()); | |
560 | hClusterChargePerChMean->SetBinError(iCh+1, hClusterChargeInCh->GetMeanError()); | |
561 | hClusterChargePerChSigma->SetBinContent(iCh+1, hClusterChargeInCh->GetRMS()); | |
562 | hClusterChargePerChSigma->SetBinError(iCh+1, hClusterChargeInCh->GetRMSError()); | |
563 | ||
564 | TH1* hClusterSizeInCh = ((TH1F*)fListExpert->UncheckedAt(kClusterSizeInCh+iCh)); | |
565 | hClusterSizePerChMean->SetBinContent(iCh+1, hClusterSizeInCh->GetMean()); | |
566 | hClusterSizePerChMean->SetBinError(iCh+1, hClusterSizeInCh->GetMeanError()); | |
567 | hClusterSizePerChSigma->SetBinContent(iCh+1, hClusterSizeInCh->GetRMS()); | |
568 | hClusterSizePerChSigma->SetBinError(iCh+1, hClusterSizeInCh->GetRMSError()); | |
569 | ||
570 | } | |
571 | ||
572 | // fill summary plots per DE | |
573 | TH2F* hClusterChargePerDE = ((TH2F*)fListExpert->UncheckedAt(kClusterChargePerDE)); | |
94ef1a28 | 574 | TH2F* hClusterSizePerDE = ((TH2F*)fListExpert->UncheckedAt(kClusterSizePerDE)); |
94ef1a28 | 575 | for (Int_t iDE = 1; iDE < nDE+1; iDE++) { |
576 | ||
577 | TH1D *tmp = hClusterChargePerDE->ProjectionY("tmp",iDE,iDE,"e"); | |
578 | if (tmp->GetEntries() > 10.) { | |
579 | hClusterChargePerDEMean->SetBinContent(iDE, tmp->GetMean()); | |
580 | hClusterChargePerDEMean->SetBinError(iDE, tmp->GetMeanError()); | |
581 | hClusterChargePerDESigma->SetBinContent(iDE, tmp->GetRMS()); | |
582 | hClusterChargePerDESigma->SetBinError(iDE, tmp->GetRMSError()); | |
583 | } | |
584 | delete tmp; | |
585 | ||
586 | tmp = hClusterSizePerDE->ProjectionY("tmp",iDE,iDE,"e"); | |
587 | if (tmp->GetEntries() > 10.) { | |
588 | hClusterSizePerDEMean->SetBinContent(iDE, tmp->GetMean()); | |
589 | hClusterSizePerDEMean->SetBinError(iDE, tmp->GetMeanError()); | |
590 | hClusterSizePerDESigma->SetBinContent(iDE, tmp->GetRMS()); | |
591 | hClusterSizePerDESigma->SetBinError(iDE, tmp->GetRMSError()); | |
592 | } | |
593 | delete tmp; | |
594 | ||
595 | } | |
596 | ||
40be9f05 | 597 | // Post summary data. |
598 | PostData(5, fListNorm); | |
94ef1a28 | 599 | } |
600 | ||
601 | //________________________________________________________________________ | |
602 | Double_t AliAnalysisTaskMuonQA::ChangeThetaRange(Double_t theta) | |
603 | { | |
03ac5989 | 604 | /// set theta range from -180 to +180 degrees |
94ef1a28 | 605 | if(theta < -2.5) return (theta / TMath::Pi() + 1.) * 180.; |
606 | else if(theta > 2.5) return (theta / TMath::Pi() - 1.) * 180.; | |
607 | else return theta / TMath::Pi() * 180.; | |
608 | } | |
609 | ||
03ac5989 | 610 | //________________________________________________________________________ |
611 | UInt_t AliAnalysisTaskMuonQA::BuildTriggerWord(TString& FiredTriggerClasses) | |
612 | { | |
613 | /// build the trigger word from the fired trigger classes and the list of selectable trigger | |
614 | ||
615 | UInt_t word = 0; | |
616 | ||
617 | TObjString* trigClasseName = 0x0; | |
618 | TIter nextTrigger(fSelectTriggerClass); | |
619 | while ((trigClasseName = static_cast<TObjString*>(nextTrigger()))) { | |
620 | ||
621 | TRegexp GenericTriggerClasseName(trigClasseName->String()); | |
622 | if (FiredTriggerClasses.Contains(GenericTriggerClasseName)) word |= trigClasseName->GetUniqueID(); | |
623 | ||
624 | } | |
625 | ||
626 | return word; | |
627 | } | |
628 | ||
629 | //________________________________________________________________________ | |
630 | TList* AliAnalysisTaskMuonQA::BuildListOfTriggerCases(TString& FiredTriggerClasses) | |
631 | { | |
632 | /// build the list of trigger for the counters from the fired trigger classes and the list of trigger classes | |
633 | /// returned TList must be deleted by user | |
634 | ||
635 | TList* list = new TList(); | |
636 | list->SetOwner(); | |
637 | ||
638 | // add case any | |
639 | list->AddLast(new TObjString("trigger:any")); | |
640 | ||
641 | TObjString* trigClasseName = 0x0; | |
642 | TIter nextTrigger(fTriggerClass); | |
643 | while ((trigClasseName = static_cast<TObjString*>(nextTrigger()))) { | |
644 | ||
645 | TRegexp GenericTriggerClasseName(trigClasseName->String()); | |
646 | if (FiredTriggerClasses.Contains(GenericTriggerClasseName)) { | |
647 | ||
648 | // add specific trigger case | |
649 | TObjString* trigShortName = static_cast<TObjString*>(fTriggerClass->GetValue(trigClasseName)); | |
650 | list->AddLast(new TObjString(Form("trigger:%s",trigShortName->GetName()))); | |
651 | ||
652 | } | |
653 | ||
654 | } | |
655 | ||
656 | // add case other if no specific trigger was found | |
657 | if (list->GetSize() == 1) list->AddLast(new TObjString("trigger:other")); | |
658 | ||
659 | return list; | |
660 | } | |
661 |