]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGPP/MUON/lite/AliAnalysisTaskMuonQA.cxx
5f449115c2f3ac121e3a884ab687413f08041c95
[u/mrichter/AliRoot.git] / PWGPP / MUON / lite / AliAnalysisTaskMuonQA.cxx
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 /* $Id$ */
17
18 #include <Riostream.h>
19
20 // ROOT includes
21 #include "TH1F.h"
22 #include "TH2F.h"
23 #include "TCanvas.h"
24 #include "TROOT.h"
25 #include "TString.h"
26 #include "TObjArray.h"
27 #include "TMath.h"
28 #include "TFile.h"
29 #include "TRegexp.h"
30 #include "TMap.h"
31 #include "TList.h"
32 #include "TObjString.h"
33
34 // STEER includes
35 #include "AliESDEvent.h"
36 #include "AliESDMuonTrack.h"
37 #include "AliESDMuonCluster.h"
38 #include "AliESDInputHandler.h"
39 #include "AliESDVZERO.h"
40
41 // ANALYSIS includes
42 #include "AliAnalysisDataSlot.h"
43 #include "AliAnalysisManager.h"
44 #include "AliAnalysisTaskMuonQA.h"
45 #include "AliCounterCollection.h"
46
47 ClassImp(AliAnalysisTaskMuonQA)
48
49 const Int_t AliAnalysisTaskMuonQA::nCh = 10;
50
51 const Int_t AliAnalysisTaskMuonQA::nDE = 1100;
52
53 const Float_t AliAnalysisTaskMuonQA::dMax[5] = {176.6, 229.0, 308.84, 418.2,  522.0}; // cm
54
55 //________________________________________________________________________
56 AliAnalysisTaskMuonQA::AliAnalysisTaskMuonQA() :
57   AliAnalysisTaskSE(), 
58   fList(0x0),
59   fListExpert(0x0),
60   fListNorm(0x0),
61   fTrackCounters(0x0),
62   fEventCounters(0x0),
63   fSelectCharge(0),
64   fSelectPhysics(kFALSE),
65   fSelectTrigger(kFALSE),
66   fTriggerMask(0),
67   fSelectMatched(kFALSE),
68   fApplyAccCut(kFALSE),
69   fTriggerClass(0x0),
70   fSelectTriggerClass(0x0)
71 {
72   // Dummy constructor
73 }
74
75 //________________________________________________________________________
76 AliAnalysisTaskMuonQA::AliAnalysisTaskMuonQA(const char *name) :
77   AliAnalysisTaskSE(name), 
78   fList(0x0),
79   fListExpert(0x0),
80   fListNorm(0x0),
81   fTrackCounters(0x0),
82   fEventCounters(0x0),
83   fSelectCharge(0),
84   fSelectPhysics(kFALSE),
85   fSelectTrigger(kFALSE),
86   fTriggerMask(0),
87   fSelectMatched(kFALSE),
88   fApplyAccCut(kFALSE),
89   fTriggerClass(0x0),
90   fSelectTriggerClass(0x0)
91 {
92   /// Constructor
93   
94   // Output slot #1 writes into a TObjArray container
95   DefineOutput(1,TObjArray::Class());
96   // Output slot #2 writes into a TObjArray container
97   DefineOutput(2,TObjArray::Class());
98   // Output slot #3 writes track counters
99   DefineOutput(3,AliCounterCollection::Class());
100   // Output slot #4 writes event counters
101   DefineOutput(4,AliCounterCollection::Class());
102   // Output slot #5 writes normalized histograms
103   DefineOutput(5,TObjArray::Class());
104 }
105
106 //________________________________________________________________________
107 AliAnalysisTaskMuonQA::~AliAnalysisTaskMuonQA()
108 {
109   /// Destructor
110   if (!AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
111     delete fList;
112     delete fListExpert;
113     delete fTrackCounters;
114     delete fEventCounters;
115     delete fListNorm;
116   }
117   delete fTriggerClass;
118   delete fSelectTriggerClass;
119 }
120
121 //___________________________________________________________________________
122 void AliAnalysisTaskMuonQA::UserCreateOutputObjects()
123 {
124   /// Create histograms and counters
125   
126   // set the list of trigger classes with corresponding short names
127   fTriggerClass = new TMap(20);
128   fTriggerClass->SetOwnerKeyValue();
129   // p-p trigger classes
130   fTriggerClass->Add(new TObjString("CBEAMB"), new TObjString("CBEAMB"));
131   fTriggerClass->Add(new TObjString("CINT1B-ABCE-NOPF-ALL"), new TObjString("CINT1B"));
132   fTriggerClass->Add(new TObjString("CMUS1B-ABCE-NOPF-MUON"), new TObjString("CMUS1B"));
133   fTriggerClass->Add(new TObjString("CINT1[AC]-"), new TObjString("CINT1AC"));
134   fTriggerClass->Add(new TObjString("CMUS1[AC]-"), new TObjString("CMUS1AC"));
135   fTriggerClass->Add(new TObjString("CINT1-E-"), new TObjString("CINT1E"));
136   fTriggerClass->Add(new TObjString("CINT5-E-"), new TObjString("CINT5E"));
137   fTriggerClass->Add(new TObjString("CMUS1-E-"), new TObjString("CMUS1E"));
138   fTriggerClass->Add(new TObjString("CMUS5-E-"), new TObjString("CMUS5E"));
139   fTriggerClass->Add(new TObjString("CINT1-B-"), new TObjString("CINT1B"));
140   fTriggerClass->Add(new TObjString("CINT5-B-"), new TObjString("CINT5B"));
141   fTriggerClass->Add(new TObjString("CMUS1-B-"), new TObjString("CMUS1B"));
142   fTriggerClass->Add(new TObjString("CMUS5-B-"), new TObjString("CMUS5B"));
143   fTriggerClass->Add(new TObjString("CINT1-AC-"), new TObjString("CINT1AC"));
144   fTriggerClass->Add(new TObjString("CINT5-AC-"), new TObjString("CINT5AC"));
145   fTriggerClass->Add(new TObjString("CMUS1-AC-"), new TObjString("CMUS1AC"));
146   fTriggerClass->Add(new TObjString("CMUS5-AC-"), new TObjString("CMUS5AC"));
147   fTriggerClass->Add(new TObjString("CSH1-B-"), new TObjString("CSH1B"));
148
149   TString side_pp[3] = {"B", "AC", "E"};
150   for(Int_t i = 0; i< 3; i++){
151     fTriggerClass->Add(new TObjString(Form("CINT7-%s-", side_pp[i].Data())), new TObjString(Form("CINT7%s",side_pp[i].Data())));
152     fTriggerClass->Add(new TObjString(Form("CMUSH7-%s-",side_pp[i].Data())), new TObjString(Form("CMUSH7%s",side_pp[i].Data())));
153     fTriggerClass->Add(new TObjString(Form("CMUL7-%s-",side_pp[i].Data())), new TObjString(Form("CMUL7%s",side_pp[i].Data())));
154     fTriggerClass->Add(new TObjString(Form("CMUU7-%s-",side_pp[i].Data())), new TObjString(Form("CMUU7%s",side_pp[i].Data())));
155     fTriggerClass->Add(new TObjString(Form("CMUS7-%s-",side_pp[i].Data())), new TObjString(Form("CMUS7%s",side_pp[i].Data())));
156   }
157   fTriggerClass->Add(new TObjString("CINT7-I-"), new TObjString("CINT7I"));
158
159   // Pb-Pb trigger classes
160   TString side[4] = {"B", "A", "C", "E"};
161   for (Int_t i = 0; i < 4; i++) {
162     fTriggerClass->Add(new TObjString(Form("CMBACS2-%s-", side[i].Data())), new TObjString(Form("CMBACS2-%s", side[i].Data())));
163     fTriggerClass->Add(new TObjString(Form("CMBS2A-%s-", side[i].Data())), new TObjString(Form("CMBS2A-%s", side[i].Data())));
164     fTriggerClass->Add(new TObjString(Form("CMBS2C-%s-", side[i].Data())), new TObjString(Form("CMBS2C-%s", side[i].Data())));
165     fTriggerClass->Add(new TObjString(Form("CMBAC-%s-", side[i].Data())), new TObjString(Form("CMBAC-%s", side[i].Data())));
166     fTriggerClass->Add(new TObjString(Form("C0SMH-%s-", side[i].Data())), new TObjString(Form("C0SMH-%s", side[i].Data())));
167   }
168   
169   // set the list of trigger classes that can be selected to fill histograms (in case the physics selection is not used)
170   fSelectTriggerClass = new TList();
171   fSelectTriggerClass->SetOwner();
172   // p-p trigger classes
173   fSelectTriggerClass->AddLast(new TObjString("CINT1B-ABCE-NOPF-ALL")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
174   fSelectTriggerClass->AddLast(new TObjString("CMUS1B-ABCE-NOPF-MUON")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUON);
175   fSelectTriggerClass->AddLast(new TObjString("CINT1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
176   fSelectTriggerClass->AddLast(new TObjString("CINT5-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kCINT5);
177   fSelectTriggerClass->AddLast(new TObjString("CMUS1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUON);
178   fSelectTriggerClass->AddLast(new TObjString("CMUS5-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kCMUS5);
179   fSelectTriggerClass->AddLast(new TObjString("CINT7-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kINT7);
180   fSelectTriggerClass->AddLast(new TObjString("CINT7-I-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kINT7);
181   fSelectTriggerClass->AddLast(new TObjString("CMUSH7-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUSH7);
182   fSelectTriggerClass->AddLast(new TObjString("CMUS7-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUS7);
183   fSelectTriggerClass->AddLast(new TObjString("CMUU7-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUU7);
184   fSelectTriggerClass->AddLast(new TObjString("CMUL7-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMUL7);
185   fSelectTriggerClass->AddLast(new TObjString("CSH1-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kHighMult);
186         
187   // Pb-Pb trigger classes
188   fSelectTriggerClass->AddLast(new TObjString("CMBACS2-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
189   fSelectTriggerClass->AddLast(new TObjString("CMBS2A-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
190   fSelectTriggerClass->AddLast(new TObjString("CMBS2C-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
191   fSelectTriggerClass->AddLast(new TObjString("CMBAC-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kMB);
192   fSelectTriggerClass->AddLast(new TObjString("C0SMH-B-")); fSelectTriggerClass->Last()->SetUniqueID(AliVEvent::kHighMult);
193   
194   // create histograms
195   fList = new TObjArray(2000);
196   fList->SetOwner();
197   fListExpert = new TObjArray(2000);
198   fListExpert->SetOwner();
199   
200   // track info
201   TH1F* hNTracks = new TH1F("hNTracks", "number of tracks;n_{tracks}", 20, 0., 20.);
202   fList->AddAtAndExpand(hNTracks, kNTracks);
203   
204   TH1F* hMatchTrig = new TH1F("hMatchTrig", "number of tracks matched with trigger;n_{tracks}", 20, 0., 20.);
205   fList->AddAtAndExpand(hMatchTrig, kMatchTrig);
206   
207   TH1F* hSign = new TH1F("hSign", "track sign;sign", 3, -1.5, 1.5);
208   fList->AddAtAndExpand(hSign, kSign);
209   
210   TH1F* hDCA = new TH1F("hDCA", "DCA distribution;DCA (cm)", 500, 0., 500.);
211   fList->AddAtAndExpand(hDCA, kDCA);
212   
213   TH1F* hP = new TH1F("hP", "momentum distribution;p (GeV/c)", 300, 0., 300.);
214   fList->AddAtAndExpand(hP, kP);
215   
216   TH1F* hPMuPlus = new TH1F("hPMuPlus", "momentum distribution of #mu^{+};p (GeV/c)", 300, 0., 300.);
217   fList->AddAtAndExpand(hPMuPlus, kPMuPlus);
218   
219   TH1F* hPMuMinus = new TH1F("hPMuMinus", "momentum distribution of #mu^{-};p (GeV/c)", 300, 0., 300.);
220   fList->AddAtAndExpand(hPMuMinus, kPMuMinus);
221   
222   Int_t nPtBins = 300;
223   Double_t ptMin = 0., ptMax = 30.;
224         
225   TH1F* hPt = new TH1F("hPt", "transverse momentum distribution;p_{t} (GeV/c)", nPtBins, ptMin, ptMax);
226   fList->AddAtAndExpand(hPt, kPt);
227   
228   TH1F* hPtMuPlus = new TH1F("hPtMuPlus", "transverse momentum distribution of #mu^{+};p_{t} (GeV/c)", nPtBins, ptMin, ptMax);
229   fList->AddAtAndExpand(hPtMuPlus, kPtMuPlus);
230   
231   TH1F* hPtMuMinus = new TH1F("hPtMuMinus", "transverse momentum distribution of #mu^{-};p_{t} (GeV/c)", nPtBins, ptMin, ptMax);
232   fList->AddAtAndExpand(hPtMuMinus, kPtMuMinus);
233   
234   TH1F* hRapidity = new TH1F("hRapidity", "rapidity distribution;rapidity", 200, -4.5, -2.);
235   fList->AddAtAndExpand(hRapidity, kRapidity);
236   
237   TH1F* hThetaX = new TH1F("hThetaX", "#theta_{X} distribution;#theta_{X} (degree)", 360, -180., 180);
238   fList->AddAtAndExpand(hThetaX, kThetaX);
239   
240   TH1F* hThetaY = new TH1F("hThetaY", "#theta_{Y} distribution;#theta_{Y} (degree)", 360, -180., 180);
241   fList->AddAtAndExpand(hThetaY, kThetaY);
242   
243   TH1F* hChi2 = new TH1F("hChi2", "normalized #chi^{2} distribution;#chi^{2} / ndf", 500, 0., 50.);
244   fList->AddAtAndExpand(hChi2, kChi2);
245   
246   TH1F* hProbChi2 = new TH1F("hProbChi2", "distribution of probability of #chi^{2};prob(#chi^{2})", 100, 0., 1.);
247   fList->AddAtAndExpand(hProbChi2, kProbChi2);
248   
249   // cluster info
250   TH1F* hNClustersPerTrack = new TH1F("hNClustersPerTrack", "number of associated clusters per track;n_{clusters}", 20, 0., 20.);
251   fList->AddAtAndExpand(hNClustersPerTrack, kNClustersPerTrack);
252   
253   TH1F* hNChamberHitPerTrack = new TH1F("hNChamberHitPerTrack", "number of chambers hit per track;n_{chamber hit}", 15, 0., 15.);
254   fList->AddAtAndExpand(hNChamberHitPerTrack, kNChamberHitPerTrack);
255   
256   // Matched tracks info
257   TH1F* hPtMatchLpt = new TH1F("hPtMatchLpt", "transverse momentum distribution matching Lpt;p_{t} (GeV/c)", nPtBins, ptMin, ptMax);
258   fList->AddAtAndExpand(hPtMatchLpt, kPtMatchLpt);
259   
260   TH1F* hPtMatchHpt = new TH1F("hPtMatchHpt", "transverse momentum distribution matching Hpt;p_{t} (GeV/c)", nPtBins, ptMin, ptMax);
261   fList->AddAtAndExpand(hPtMatchHpt, kPtMatchHpt);
262   
263   TH1F* hPtMuPlusMatchLpt = new TH1F("hPtMuPlusMatchLpt", "transverse momentum distribution of #mu^{+} matching Lpt;p_{t} (GeV/c)", nPtBins, ptMin, ptMax);
264   fList->AddAtAndExpand(hPtMuPlusMatchLpt, kPtMuPlusMatchLpt);
265
266   TH1F* hPtMuPlusMatchHpt = new TH1F("hPtMuPlusMatchHpt", "transverse momentum distribution of #mu^{+} matching Hpt;p_{t} (GeV/c)", nPtBins, ptMin, ptMax);
267   fList->AddAtAndExpand(hPtMuPlusMatchHpt, kPtMuPlusMatchHpt);
268   
269   TH1F* hPtMuMinusMatchLpt = new TH1F("hPtMuMinusMatchLpt", "transverse momentum distribution of #mu^{-} matching Lpt;p_{t} (GeV/c)", nPtBins, ptMin, ptMax);
270   fList->AddAtAndExpand(hPtMuMinusMatchLpt, kPtMuMinusMatchLpt);
271   
272   TH1F* hPtMuMinusMatchHpt = new TH1F("hPtMuMinusMatchHpt", "transverse momentum distribution of #mu^{-} matching Hpt;p_{t} (GeV/c)", nPtBins, ptMin, ptMax);
273   fList->AddAtAndExpand(hPtMuMinusMatchHpt, kPtMuMinusMatchHpt);  
274         
275   TH1F* hNClustersPerCh = new TH1F("hNClustersPerCh", "averaged number of clusters per chamber per track;chamber ID;<n_{clusters}>", nCh, -0.5, nCh-0.5);
276   hNClustersPerCh->Sumw2();
277   hNClustersPerCh->SetOption("P");
278   hNClustersPerCh->SetMarkerStyle(kFullDotMedium);
279   hNClustersPerCh->SetMarkerColor(kBlue);
280   fListExpert->AddAtAndExpand(hNClustersPerCh, kNClustersPerCh);
281   
282   TH1F* hNClustersPerDE = new TH1F("hNClustersPerDE", "averaged number of clusters per DE per track;DetElem ID;<n_{clusters}>", nDE+1, -0.5, nDE+0.5);
283   hNClustersPerDE->Sumw2();
284   hNClustersPerDE->SetOption("P");
285   hNClustersPerDE->SetMarkerStyle(kFullDotMedium);
286   hNClustersPerDE->SetMarkerColor(kBlue);
287   fListExpert->AddAtAndExpand(hNClustersPerDE, kNClustersPerDE);
288   
289   for (Int_t i = 0; i < nCh; i++) {
290     Float_t rMax = 0.5*dMax[i/2];
291     TH2F* hClusterHitMapInCh = new TH2F(Form("hClusterHitMapInCh%d",i+1), Form("cluster position distribution in chamber %d;X (cm);Y (cm)",i+1),
292                                         100, -rMax, rMax, 100, -rMax, rMax);
293     fListExpert->AddAtAndExpand(hClusterHitMapInCh, kClusterHitMapInCh+i);
294     
295     TH1F* hClusterChargeInCh = new TH1F(Form("hClusterChargeInCh%d",i+1), Form("cluster charge distribution in chamber %d;charge (fC)",i+1), 100, 0., 1000.);
296     fListExpert->AddAtAndExpand(hClusterChargeInCh, kClusterChargeInCh+i);
297     
298     TH1F* hClusterSizeInCh = new TH1F(Form("hClusterSizeInCh%d",i+1), Form("cluster size distribution in chamber %d;size (n_{pads})",i+1), 200, 0., 200.);
299     fListExpert->AddAtAndExpand(hClusterSizeInCh, kClusterSizeInCh+i);
300   }
301   
302   TH2F* hClusterChargePerDE = new TH2F("hClusterChargePerDE", "cluster charge distribution per DE;DetElem ID;charge (fC)", nDE+1, -0.5, nDE+0.5, 100, 0., 1000.);
303   fListExpert->AddAtAndExpand(hClusterChargePerDE, kClusterChargePerDE);
304   
305   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.);
306   fListExpert->AddAtAndExpand(hClusterSizePerDE, kClusterSizePerDE);
307   
308   // initialize track counters
309   fTrackCounters = new AliCounterCollection("trackCounters");
310   fTrackCounters->AddRubric("track", "trackeronly/triggeronly/matched");
311   fTrackCounters->AddRubric("trigger", 1000000);
312   fTrackCounters->AddRubric("run", 1000000);
313   fTrackCounters->AddRubric("selected", "yes/no");
314   fTrackCounters->AddRubric("triggerRO", "good/bad");
315   fTrackCounters->AddRubric("v0mult", "low/int/high/any");
316   fTrackCounters->AddRubric("charge", "pos/neg/any");
317   fTrackCounters->AddRubric("pt", "low/high/any");
318   fTrackCounters->AddRubric("acc", "in/out");
319   fTrackCounters->Init();
320   
321   // initialize event counters
322   fEventCounters = new AliCounterCollection("eventCounters");
323   fEventCounters->AddRubric("event", "muon/any");
324   fEventCounters->AddRubric("trigger", 1000000);
325   fEventCounters->AddRubric("run", 1000000);
326   fEventCounters->AddRubric("selected", "yes/no");
327   fEventCounters->AddRubric("triggerRO", "good/bad");
328   fEventCounters->AddRubric("v0mult", "low/int/high/any");
329   fEventCounters->Init();
330   
331   // Post data at least once per task to ensure data synchronisation (required for merging)
332   PostData(1, fList);
333   PostData(2, fListExpert);
334   PostData(3, fTrackCounters);
335   PostData(4, fEventCounters);
336 }
337
338 //________________________________________________________________________
339 void AliAnalysisTaskMuonQA::UserExec(Option_t *)
340 {
341   /// Called for each event
342   
343   AliESDEvent* fESD = dynamic_cast<AliESDEvent*>(InputEvent());
344   if (!fESD) {
345     Printf("ERROR: fESD not available");
346     return;
347   }
348   
349   // check physics selection
350   UInt_t triggerWord = (fInputHandler) ? fInputHandler->IsEventSelected() : 0;
351   Bool_t isPhysicsSelected = (triggerWord != 0);
352   TString selected = isPhysicsSelected ? "selected:yes" : "selected:no";
353   
354   // check trigger selection 
355   TString FiredTriggerClasses = fESD->GetFiredTriggerClasses();
356   if (!fSelectPhysics) triggerWord = BuildTriggerWord(FiredTriggerClasses);
357   Bool_t isTriggerSelected = ((triggerWord & fTriggerMask) != 0);
358   
359   // get the V0 multiplicity (except for p-p)
360   AliESDVZERO* v0Data = fESD->GetVZEROData();
361   Float_t v0Mult = 0.;
362   if (v0Data && strcmp(fESD->GetBeamType(),"p-p"))
363     for (Int_t i = 0 ; i < 64 ; i++) v0Mult += v0Data->GetMultiplicity(i);
364   TList listV0MultKey;
365   listV0MultKey.SetOwner();
366   listV0MultKey.AddLast(new TObjString("v0mult:any"));
367   //if (v0Mult > 239. && v0Mult < 559.) listV0MultKey.AddLast(new TObjString("v0mult:low"));
368   if (v0Mult >= 239. && v0Mult < 1165.) listV0MultKey.AddLast(new TObjString("v0mult:low"));
369   else if (v0Mult >= 1165. && v0Mult < 12191.) listV0MultKey.AddLast(new TObjString("v0mult:int"));
370   else if (v0Mult >= 12191. && v0Mult < 20633.) listV0MultKey.AddLast(new TObjString("v0mult:high"));
371   TIter nextV0MultKey(&listV0MultKey);
372   
373   // first loop over tracks to check for trigger readout problem
374   Int_t maxTriggerRO = (!strcmp(fESD->GetBeamType(),"p-p")) ? 10 : 1000;
375   Int_t nTracks = (Int_t) fESD->GetNumberOfMuonTracks();
376   Int_t nTriggerTracks = 0;
377   for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack)
378     if (fESD->GetMuonTrack(iTrack)->ContainTriggerData()) nTriggerTracks++;
379   TString triggerRO = (nTriggerTracks < maxTriggerRO) ? "triggerRO:good" : "triggerRO:bad";
380   
381   // --- fill event counters ---
382   
383   // build the list of trigger cases
384   //TList* triggerCases = BuildListOfTriggerCases(FiredTriggerClasses);
385   TList* triggerCases = BuildListOfAllTriggerCases(FiredTriggerClasses);
386
387   // loop over trigger cases
388   TObjString* triggerKey = 0x0;
389   TIter nextTriggerCase(triggerCases);
390   while ((triggerKey = static_cast<TObjString*>(nextTriggerCase()))) {
391     
392     // loop over V0Mult cases
393     TObjString* v0MultKey = 0x0;
394     nextV0MultKey.Reset();
395     while ((v0MultKey = static_cast<TObjString*>(nextV0MultKey()))) {
396       
397       // any event
398       fEventCounters->Count(Form("event:any/%s/run:%d/%s/%s/%s", triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), v0MultKey->GetName()));
399       
400       // muon event
401       if (nTracks > 0) fEventCounters->Count(Form("event:muon/%s/run:%d/%s/%s/%s", triggerKey->GetName(), fCurrentRunNumber, selected.Data(), triggerRO.Data(), v0MultKey->GetName()));
402       
403     }
404       
405   }
406   
407   // second loop over tracks to fill histograms and track counters
408   Int_t nSelectedTrackerTracks = 0;
409   Int_t nSelectedTrackMatchTrig = 0;
410   Int_t nPVTracks = fESD->GetPrimaryVertex()->GetNContributors();
411   for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack) {
412     
413     // get the ESD track
414     AliESDMuonTrack* esdTrack = fESD->GetMuonTrack(iTrack);
415     
416     // --- fill track counters ---
417     
418     // define the key words
419     TString trackKey = "track:";
420     TString chargeKey = "charge:";
421     TString accKey = "acc:";
422     Bool_t lowPt = kFALSE;
423     Bool_t highPt = kFALSE;
424     if (esdTrack->ContainTrackerData()) {
425       
426       if (esdTrack->ContainTriggerData()) trackKey += "matched";
427       else  trackKey += "trackeronly";
428       
429       Short_t trackCharge = esdTrack->Charge();
430       if (trackCharge < 0) chargeKey += "neg";
431       else chargeKey += "pos";
432       
433       Double_t thetaTrackAbsEnd = TMath::ATan(esdTrack->GetRAtAbsorberEnd()/505.) * TMath::RadToDeg();
434       Double_t trackPt = esdTrack->Pt();
435       Double_t eta = esdTrack->Eta();
436       if (trackPt > 1. && nPVTracks>0 && thetaTrackAbsEnd>2. && thetaTrackAbsEnd < 10. && eta > -4. && eta < -2.5) lowPt = kTRUE;
437       if (trackPt > 2. && nPVTracks>0 && thetaTrackAbsEnd>2. && thetaTrackAbsEnd < 10. && eta > -4. && eta < -2.5) highPt = kTRUE;
438       
439       if (thetaTrackAbsEnd < 2. || thetaTrackAbsEnd > 10. || eta < -4. || eta > -2.5) accKey += "out";
440       else accKey += "in";
441       
442     } else {
443       
444       trackKey += "triggeronly";
445       chargeKey = ""; // ghost have no charge specified
446       accKey += "out"; // ghost are labelled out of the acceptance
447       
448     }
449     
450     // loop over trigger cases and fill counters
451     nextTriggerCase.Reset();
452     while ((triggerKey = static_cast<TObjString*>(nextTriggerCase()))) {
453       
454       // loop over V0Mult cases
455       TObjString* v0MultKey = 0x0;
456       nextV0MultKey.Reset();
457       while ((v0MultKey = static_cast<TObjString*>(nextV0MultKey()))) {
458         
459         // any charge / any pt
460         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()));
461         
462         // any charge / specific pt
463         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()));
464         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()));
465         
466         if (!chargeKey.IsNull()) {
467           
468           // specific charge / any pt
469           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()));
470           
471           // specific charge / specific pt
472           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()));
473           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()));
474           
475         }
476         
477       }
478       
479     }
480     
481     // --- apply selections and fill histograms with selected tracks ---
482     
483     // remove "ghost"
484     if (!esdTrack->ContainTrackerData()) continue;
485     
486     // select on "physics" before filling histograms
487     if (fSelectPhysics && !isPhysicsSelected) continue;
488     
489     // select on trigger before filling histograms
490     if (fSelectTrigger && !isTriggerSelected) continue;
491     
492     // select on track charge
493     if (fSelectCharge*esdTrack->Charge() < 0) continue;
494     
495     // select on track matching
496     if (fSelectMatched && !esdTrack->ContainTriggerData()) continue;
497     
498     // skip tracks that do not pass the acceptance cuts if required
499     if (fApplyAccCut && accKey.EndsWith("out")) continue;
500     
501     nSelectedTrackerTracks++;
502     if (esdTrack->ContainTriggerData()) nSelectedTrackMatchTrig++;
503     
504     Double_t trackP = esdTrack->P();
505     Double_t trackPt = esdTrack->Pt();
506     Short_t trackCharge = esdTrack->Charge();
507     ((TH1F*)fList->UncheckedAt(kP))->Fill(trackP);
508     ((TH1F*)fList->UncheckedAt(kPt))->Fill(trackPt);
509     Bool_t matchTrigLpt = (esdTrack->GetMatchTrigger()>=2);
510     Bool_t matchTrigHpt = (esdTrack->GetMatchTrigger()>=3);
511     if ( matchTrigLpt ) ((TH1F*)fList->UncheckedAt(kPtMatchLpt))->Fill(trackPt);
512     if ( matchTrigHpt ) ((TH1F*)fList->UncheckedAt(kPtMatchHpt))->Fill(trackPt);
513     if (trackCharge < 0) {
514       ((TH1F*)fList->UncheckedAt(kPMuMinus))->Fill(trackP);
515       ((TH1F*)fList->UncheckedAt(kPtMuMinus))->Fill(trackPt);
516       if ( matchTrigLpt ) ((TH1F*)fList->UncheckedAt(kPtMuMinusMatchLpt))->Fill(trackPt);
517       if ( matchTrigHpt ) ((TH1F*)fList->UncheckedAt(kPtMuMinusMatchHpt))->Fill(trackPt);
518     } else {
519       ((TH1F*)fList->UncheckedAt(kPMuPlus))->Fill(trackP);
520       ((TH1F*)fList->UncheckedAt(kPtMuPlus))->Fill(trackPt);
521       if ( matchTrigLpt ) ((TH1F*)fList->UncheckedAt(kPtMuPlusMatchLpt))->Fill(trackPt);
522       if ( matchTrigHpt ) ((TH1F*)fList->UncheckedAt(kPtMuPlusMatchHpt))->Fill(trackPt);
523     }
524     ((TH1F*)fList->UncheckedAt(kRapidity))->Fill(esdTrack->Y());
525     Int_t ndf = 2 * esdTrack->GetNHit() - 5;
526     ((TH1F*)fList->UncheckedAt(kChi2))->Fill(esdTrack->GetChi2()/ndf);
527     ((TH1F*)fList->UncheckedAt(kProbChi2))->Fill(TMath::Prob(esdTrack->GetChi2(),ndf));
528     ((TH1F*)fList->UncheckedAt(kThetaX))->Fill(ChangeThetaRange(esdTrack->GetThetaXUncorrected()));
529     ((TH1F*)fList->UncheckedAt(kThetaY))->Fill(ChangeThetaRange(esdTrack->GetThetaYUncorrected()));
530     ((TH1F*)fList->UncheckedAt(kNClustersPerTrack))->Fill(esdTrack->GetNHit());
531     ((TH1F*)fList->UncheckedAt(kSign))->Fill(trackCharge);
532     ((TH1F*)fList->UncheckedAt(kDCA))->Fill(esdTrack->GetDCA());
533     
534     Int_t nChamberHit = 0;
535     for (Int_t ich=0; ich<10; ich++) if (esdTrack->IsInMuonClusterMap(ich)) nChamberHit++;
536     ((TH1F*)fList->UncheckedAt(kNChamberHitPerTrack))->Fill(nChamberHit);
537     
538     // loop over clusters
539     for (Int_t icl=0; icl<esdTrack->GetNClusters(); icl++) {
540       
541       AliESDMuonCluster* esdCluster = esdTrack->GetESDEvent()->FindMuonCluster(esdTrack->GetClusterId(icl));
542       
543       Int_t chId = esdCluster->GetChamberId();
544       Int_t deId = esdCluster->GetDetElemId();
545       
546       ((TH1F*)fListExpert->UncheckedAt(kNClustersPerCh))->Fill(chId);
547       ((TH1F*)fListExpert->UncheckedAt(kNClustersPerDE))->Fill(deId);
548       
549       ((TH1F*)fListExpert->UncheckedAt(kClusterHitMapInCh+chId))->Fill(esdCluster->GetX(), esdCluster->GetY());
550       
551       ((TH1F*)fListExpert->UncheckedAt(kClusterChargeInCh+chId))->Fill(esdCluster->GetCharge());
552       ((TH1F*)fListExpert->UncheckedAt(kClusterChargePerDE))->Fill(deId, esdCluster->GetCharge());
553       
554       if (esdCluster->PadsStored()) { // discard clusters with pad not stored in ESD
555         ((TH1F*)fListExpert->UncheckedAt(kClusterSizeInCh+chId))->Fill(esdCluster->GetNPads());
556         ((TH1F*)fListExpert->UncheckedAt(kClusterSizePerDE))->Fill(deId, esdCluster->GetNPads());
557       }
558       
559     }
560     
561   }
562   
563   if ((!fSelectPhysics || isPhysicsSelected) && (!fSelectTrigger || isTriggerSelected)) {
564     ((TH1F*)fList->UncheckedAt(kNTracks))->Fill(nSelectedTrackerTracks);
565     ((TH1F*)fList->UncheckedAt(kMatchTrig))->Fill(nSelectedTrackMatchTrig);
566   }
567   
568   // clean memory
569   delete triggerCases;
570   
571   // Post final data. It will be written to a file with option "RECREATE"
572   PostData(1, fList);
573   PostData(2, fListExpert);
574   PostData(3, fTrackCounters);
575   PostData(4, fEventCounters);
576 }
577
578 //________________________________________________________________________
579 void AliAnalysisTaskMuonQA::Terminate(Option_t *)
580 {
581   /// Normalize histograms
582   /// Draw result to the screen
583   /// Print statistics
584   
585   // global statistic
586   fTrackCounters = static_cast<AliCounterCollection*>(GetOutputData(3));
587   fEventCounters = static_cast<AliCounterCollection*>(GetOutputData(4));
588   if (fTrackCounters && fEventCounters) {
589     if (!gROOT->IsBatch()) {
590       cout<<"whole statistics without selection:"<<endl;
591       fEventCounters->Print("trigger/event");
592       fTrackCounters->Print("trigger/track");
593       cout<<"whole statistics of selected events:"<<endl;
594       fEventCounters->Print("trigger/event","selected:yes");
595       fTrackCounters->Print("trigger/track","selected:yes");
596       new TCanvas();
597       fEventCounters->Draw("event","trigger","");
598       new TCanvas();
599       fTrackCounters->Draw("track","trigger","");
600       new TCanvas();
601       fEventCounters->Draw("event","trigger","selected:yes");
602       new TCanvas();
603       fTrackCounters->Draw("track","trigger","selected:yes");
604     }
605   }
606   
607   // recover output histograms
608   fList = static_cast<TObjArray*>(GetOutputData(1));
609   fListExpert = static_cast<TObjArray*>(GetOutputData(2));
610   if (!fList || !fListExpert) return;
611   
612   // create summary plots
613   fListNorm = new TObjArray(1000);
614   fListNorm->SetOwner();
615   
616   // mean/dispersion of cluster charge per chamber/DE
617   TH1F* hClusterChargePerChMean = new TH1F("hClusterChargePerChMean", "cluster mean charge per chamber;chamber ID;<charge> (fC)", nCh, -0.5, nCh-0.5);
618   hClusterChargePerChMean->SetOption("P");
619   hClusterChargePerChMean->SetMarkerStyle(kFullDotMedium);
620   hClusterChargePerChMean->SetMarkerColor(kBlue);
621   fListNorm->AddAtAndExpand(hClusterChargePerChMean, kClusterChargePerChMean);
622   
623   TH1F* hClusterChargePerChSigma = new TH1F("hClusterChargePerChSigma", "cluster charge dispersion per chamber;chamber ID;#sigma_{charge} (fC)", nCh, -0.5, nCh-0.5);
624   hClusterChargePerChSigma->SetOption("P");
625   hClusterChargePerChSigma->SetMarkerStyle(kFullDotMedium);
626   hClusterChargePerChSigma->SetMarkerColor(kBlue);
627   fListNorm->AddAtAndExpand(hClusterChargePerChSigma, kClusterChargePerChSigma);
628   
629   TH1F* hClusterChargePerDEMean = new TH1F("hClusterChargePerDEMean", "cluster mean charge per DE;DetElem ID;<charge> (fC)", nDE+1, -0.5, nDE+0.5);
630   hClusterChargePerDEMean->SetOption("P");
631   hClusterChargePerDEMean->SetMarkerStyle(kFullDotMedium);
632   hClusterChargePerDEMean->SetMarkerColor(kBlue);
633   fListNorm->AddAtAndExpand(hClusterChargePerDEMean, kClusterChargePerDEMean);
634   
635   TH1F* hClusterChargePerDESigma = new TH1F("hClusterChargePerDESigma", "cluster charge dispersion per DE;DetElem ID;#sigma_{charge} (fC)", nDE+1, -0.5, nDE+0.5);
636   hClusterChargePerDESigma->SetOption("P");
637   hClusterChargePerDESigma->SetMarkerStyle(kFullDotMedium);
638   hClusterChargePerDESigma->SetMarkerColor(kBlue);
639   fListNorm->AddAtAndExpand(hClusterChargePerDESigma, kClusterChargePerDESigma);
640   
641   // mean/dispersion of cluster size per chamber/DE
642   TH1F* hClusterSizePerChMean = new TH1F("hClusterSizePerChMean", "cluster mean size per chamber;chamber ID;<size> (n_{pads})", nCh, -0.5, nCh-0.5);
643   hClusterSizePerChMean->SetOption("P");
644   hClusterSizePerChMean->SetMarkerStyle(kFullDotMedium);
645   hClusterSizePerChMean->SetMarkerColor(kBlue);
646   fListNorm->AddAtAndExpand(hClusterSizePerChMean, kClusterSizePerChMean);
647   
648   TH1F* hClusterSizePerChSigma = new TH1F("hClusterSizePerChSigma", "cluster size dispersion per chamber;chamber ID;#sigma_{size} (n_{pads})", nCh, -0.5, nCh-0.5);
649   hClusterSizePerChSigma->SetOption("P");
650   hClusterSizePerChSigma->SetMarkerStyle(kFullDotMedium);
651   hClusterSizePerChSigma->SetMarkerColor(kBlue);
652   fListNorm->AddAtAndExpand(hClusterSizePerChSigma, kClusterSizePerChSigma);
653   
654   TH1F* hClusterSizePerDEMean = new TH1F("hClusterSizePerDEMean", "cluster mean size per DE;DetElem ID;<size> (n_{pads})", nDE+1, -0.5, nDE+0.5);
655   hClusterSizePerDEMean->SetOption("P");
656   hClusterSizePerDEMean->SetMarkerStyle(kFullDotMedium);
657   hClusterSizePerDEMean->SetMarkerColor(kBlue);
658   fListNorm->AddAtAndExpand(hClusterSizePerDEMean, kClusterSizePerDEMean);
659   
660   TH1F* hClusterSizePerDESigma = new TH1F("hClusterSizePerDESigma", "cluster size dispersion per DE;DetElem ID;#sigma_{size} (n_{pads})", nDE+1, -0.5, nDE+0.5);
661   hClusterSizePerDESigma->SetOption("P");
662   hClusterSizePerDESigma->SetMarkerStyle(kFullDotMedium);
663   hClusterSizePerDESigma->SetMarkerColor(kBlue);
664   fListNorm->AddAtAndExpand(hClusterSizePerDESigma, kClusterSizePerDESigma);
665   
666   // normalize histograms
667   Float_t nTracks = ((TH1F*)fList->UncheckedAt(kNClustersPerTrack))->GetEntries();
668   if (nTracks > 0.) {
669     ((TH1F*)fListExpert->UncheckedAt(kNClustersPerCh))->Scale(1./nTracks);
670     ((TH1F*)fListExpert->UncheckedAt(kNClustersPerDE))->Scale(1./nTracks);
671   }
672   fListNorm->AddAtAndExpand(((TH1F*)fListExpert->UncheckedAt(kNClustersPerCh))->Clone(), kNClustersPerChPerTrack);
673   fListNorm->AddAtAndExpand(((TH1F*)fListExpert->UncheckedAt(kNClustersPerDE))->Clone(), kNClustersPerDEPerTrack);
674   
675   // fill summary plots per chamber
676   for (Int_t iCh = 0; iCh < nCh; iCh++) {
677     
678     TH1* hClusterChargeInCh = ((TH1F*)fListExpert->UncheckedAt(kClusterChargeInCh+iCh));
679     hClusterChargePerChMean->SetBinContent(iCh+1, hClusterChargeInCh->GetMean());
680     hClusterChargePerChMean->SetBinError(iCh+1, hClusterChargeInCh->GetMeanError());
681     hClusterChargePerChSigma->SetBinContent(iCh+1, hClusterChargeInCh->GetRMS());
682     hClusterChargePerChSigma->SetBinError(iCh+1, hClusterChargeInCh->GetRMSError());
683     
684     TH1* hClusterSizeInCh = ((TH1F*)fListExpert->UncheckedAt(kClusterSizeInCh+iCh));
685     hClusterSizePerChMean->SetBinContent(iCh+1, hClusterSizeInCh->GetMean());
686     hClusterSizePerChMean->SetBinError(iCh+1, hClusterSizeInCh->GetMeanError());
687     hClusterSizePerChSigma->SetBinContent(iCh+1, hClusterSizeInCh->GetRMS());
688     hClusterSizePerChSigma->SetBinError(iCh+1, hClusterSizeInCh->GetRMSError());
689     
690   }
691   
692   // fill summary plots per DE
693   TH2F* hClusterChargePerDE = ((TH2F*)fListExpert->UncheckedAt(kClusterChargePerDE));
694   TH2F* hClusterSizePerDE = ((TH2F*)fListExpert->UncheckedAt(kClusterSizePerDE));
695   for (Int_t iDE = 1; iDE < nDE+1; iDE++) {
696     
697     TH1D *tmp = hClusterChargePerDE->ProjectionY("tmp",iDE,iDE,"e");
698     if (tmp->GetEntries() > 10.) {
699       hClusterChargePerDEMean->SetBinContent(iDE, tmp->GetMean());
700       hClusterChargePerDEMean->SetBinError(iDE, tmp->GetMeanError());
701       hClusterChargePerDESigma->SetBinContent(iDE, tmp->GetRMS());
702       hClusterChargePerDESigma->SetBinError(iDE, tmp->GetRMSError());
703     }
704     delete tmp;
705     
706     tmp = hClusterSizePerDE->ProjectionY("tmp",iDE,iDE,"e");
707     if (tmp->GetEntries() > 10.) {
708       hClusterSizePerDEMean->SetBinContent(iDE, tmp->GetMean());
709       hClusterSizePerDEMean->SetBinError(iDE, tmp->GetMeanError());
710       hClusterSizePerDESigma->SetBinContent(iDE, tmp->GetRMS());
711       hClusterSizePerDESigma->SetBinError(iDE, tmp->GetRMSError());
712     }
713     delete tmp;
714     
715   }
716   
717   // Post summary data.
718   PostData(5, fListNorm);
719 }
720
721 //________________________________________________________________________
722 Double_t AliAnalysisTaskMuonQA::ChangeThetaRange(Double_t theta)
723 {
724   /// set theta range from -180 to +180 degrees
725   if(theta < -2.5) return (theta / TMath::Pi() + 1.) * 180.;
726   else if(theta > 2.5) return (theta / TMath::Pi() - 1.) * 180.;
727   else return theta / TMath::Pi() * 180.;
728 }
729
730 //________________________________________________________________________
731 UInt_t AliAnalysisTaskMuonQA::BuildTriggerWord(TString& FiredTriggerClasses)
732 {
733   /// build the trigger word from the fired trigger classes and the list of selectable trigger
734   
735   UInt_t word = 0;
736   
737   TObjString* trigClasseName = 0x0;
738   TIter nextTrigger(fSelectTriggerClass);
739   while ((trigClasseName = static_cast<TObjString*>(nextTrigger()))) {
740     
741     TRegexp GenericTriggerClasseName(trigClasseName->String());
742     if (FiredTriggerClasses.Contains(GenericTriggerClasseName)) word |= trigClasseName->GetUniqueID();
743     
744   }
745   
746   return word;
747 }
748
749 //________________________________________________________________________
750 TList* AliAnalysisTaskMuonQA::BuildListOfAllTriggerCases(TString& FiredTriggerClasses)
751 {
752   /// build the list of trigger for the counters from the fired trigger classes
753   /// returned TList must be deleted by user
754   
755   TList* list = new TList();
756   list->SetOwner();
757   
758   // add case any
759   list->AddLast(new TObjString("trigger:any"));
760   
761   TObjArray *obj = FiredTriggerClasses.Tokenize(" ");
762   if ( obj ){
763     TIter nextTrigger(obj);
764     TObjString* trigClasseName;
765     while ((trigClasseName = static_cast<TObjString*>(nextTrigger()))) {
766                         
767       //AliInfo(Form("trigger name %s %s",trigClasseName->GetName(),FiredTriggerClasses.Data()));
768                         
769       //Add specific trigger
770       list->AddLast(new TObjString(Form("trigger:%s",trigClasseName->GetName())));
771     }
772     delete obj;
773   }
774   
775   // add case other if no specific trigger was found
776   if (list->GetSize() == 1) list->AddLast(new TObjString("trigger:other"));
777         
778   return list;
779 }
780
781
782 //________________________________________________________________________
783 TList* AliAnalysisTaskMuonQA::BuildListOfSelectedTriggerCases(TString& FiredTriggerClasses)
784 {
785   /// build the list of trigger for the counters from the fired trigger classes
786   /// returned TList must be deleted by user
787   
788   TList* list = new TList();
789   list->SetOwner();
790   
791   // add case any
792   list->AddLast(new TObjString("trigger:any"));
793   
794   TObjString* trigClasseName = 0x0;
795   TObjArray *obj = FiredTriggerClasses.Tokenize(" ");
796   if ( obj ){
797     TIter nextTrigger(obj);
798     while ((trigClasseName = static_cast<TObjString*>(nextTrigger()))) {
799                         
800       //AliInfo(Form("trigger name %s %s",trigClasseName->GetName(),FiredTriggerClasses.Data()));
801       //loop on rejected trigger if (trigClasseName.Contains()
802       //Add specific trigger
803       list->AddLast(new TObjString(Form("trigger:%s",trigClasseName->GetName())));
804     }
805     delete obj;
806   }
807   
808   // add case other if no specific trigger was found
809   if (list->GetSize() == 1) list->AddLast(new TObjString("trigger:other"));
810         
811   return list;
812 }
813
814 //________________________________________________________________________
815 TList* AliAnalysisTaskMuonQA::BuildListOfTriggerCases(TString& FiredTriggerClasses)
816 {
817   /// build the list of trigger for the counters from the fired trigger classes and the list of trigger classes
818   /// returned TList must be deleted by user
819   
820   TList* list = new TList();
821   list->SetOwner();
822   Bool_t foundCINT1B = kFALSE;
823   Bool_t foundCMUS1B = kFALSE;
824   
825   // add case any
826   list->AddLast(new TObjString("trigger:any"));
827   
828   TObjString* trigClasseName = 0x0;
829         
830   TIter nextTrigger(fTriggerClass);
831   while ((trigClasseName = static_cast<TObjString*>(nextTrigger()))) {
832     
833     //AliInfo(Form("trigger name %s %s",trigClasseName->GetName(),FiredTriggerClasses.Data()));
834     //  cout<<"trigger name loop on "<<trigClasseName->GetName()<<" to look for "<<FiredTriggerClasses.Data()<<endl;
835     TRegexp GenericTriggerClasseName(trigClasseName->String());
836     if (FiredTriggerClasses.Contains(GenericTriggerClasseName)) {
837       //AliInfo(Form("trigger names match = %s %s",trigClasseName->GetName(),FiredTriggerClasses.Data()));
838       //cout<<"trigger names match "<<trigClasseName->GetName()<<" and "<<FiredTriggerClasses.Data()<<endl;
839       // add specific trigger case
840       TObjString* trigShortName = static_cast<TObjString*>(fTriggerClass->GetValue(trigClasseName));
841       list->AddLast(new TObjString(Form("trigger:%s",trigShortName->GetName())));
842       
843       // check for CINT1B and CMUS1B trigger
844       if (trigShortName->String() == "CINT1B") foundCINT1B = kTRUE;
845       else if (trigShortName->String() == "CMUS1B") foundCMUS1B = kTRUE;
846     }
847   }
848         
849   // add the special case CINT1B+CMUS1B
850   if (foundCINT1B && foundCMUS1B) list->AddLast(new TObjString("trigger:CINT1B+CMUS1B"));
851          
852   return list;
853 }
854