]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ANALYSIS/AliAnalysisTaskPIDqa.cxx
Revert wrong commit
[u/mrichter/AliRoot.git] / ANALYSIS / AliAnalysisTaskPIDqa.cxx
1 /**************************************************************************\r
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *\r
3  *                                                                        *\r
4  * Author: The ALICE Off-line Project.                                    *\r
5  * Contributors are mentioned in the code where appropriate.              *\r
6  *                                                                        *\r
7  * Permission to use, copy, modify and distribute this software and its   *\r
8  * documentation strictly for non-commercial purposes is hereby granted   *\r
9  * without fee, provided that the above copyright notice appears in all   *\r
10  * copies and that both the copyright notice and this permission notice   *\r
11  * appear in the supporting documentation. The authors make no claims     *\r
12  * about the suitability of this software for any purpose. It is          *\r
13  * provided "as is" without express or implied warranty.                  *\r
14  **************************************************************************/\r
15 \r
16 /* $Id: AliAnalysisTaskPIDqa.cxx 43811 2010-09-23 14:13:31Z wiechula $ */\r
17 #include <TList.h>\r
18 #include <TVectorD.h>\r
19 #include <TObjArray.h>\r
20 #include <TH2.h>\r
21 #include <TFile.h>\r
22 #include <TPRegexp.h>\r
23 #include <TChain.h>\r
24 #include <TF1.h>\r
25 #include <TSpline.h>\r
26 \r
27 #include <AliAnalysisManager.h>\r
28 #include <AliInputEventHandler.h>\r
29 #include <AliVEventHandler.h>\r
30 #include <AliVEvent.h>\r
31 #include <AliVParticle.h>\r
32 #include <AliVTrack.h>\r
33 #include <AliLog.h>\r
34 #include <AliPID.h>\r
35 #include <AliPIDResponse.h>\r
36 #include <AliITSPIDResponse.h>\r
37 #include <AliTPCPIDResponse.h>\r
38 #include <AliTRDPIDResponse.h>\r
39 #include <AliTOFPIDResponse.h>\r
40 \r
41 #include <AliESDEvent.h>\r
42 #include <AliAODEvent.h>\r
43 #include <AliESDv0.h>\r
44 #include <AliAODv0.h>\r
45 #include <AliESDv0KineCuts.h>\r
46 \r
47 #include "AliAnalysisTaskPIDqa.h"\r
48 \r
49 \r
50 ClassImp(AliAnalysisTaskPIDqa)\r
51 \r
52 //______________________________________________________________________________\r
53 AliAnalysisTaskPIDqa::AliAnalysisTaskPIDqa():\r
54 AliAnalysisTaskSE(),\r
55 fPIDResponse(0x0),\r
56 fV0cuts(0x0),\r
57 fV0electrons(0x0),\r
58 fV0pions(0x0),\r
59 fV0kaons(0x0),\r
60 fV0protons(0x0),\r
61 fListQA(0x0),\r
62 fListQAits(0x0),\r
63 fListQAitsSA(0x0),\r
64 fListQAitsPureSA(0x0),\r
65 fListQAtpc(0x0),\r
66 fListQAtrd(0x0),\r
67 fListQAtof(0x0),\r
68 fListQAt0(0x0),\r
69 fListQAemcal(0x0),\r
70 fListQAhmpid(0x0),\r
71 fListQAtofhmpid(0x0),\r
72 fListQAtpctof(0x0),\r
73 fListQAV0(0x0),\r
74 fListQAinfo(0x0)\r
75 {\r
76   //\r
77   // Dummy constructor\r
78   //\r
79 }\r
80 \r
81 //______________________________________________________________________________\r
82 AliAnalysisTaskPIDqa::AliAnalysisTaskPIDqa(const char* name):\r
83 AliAnalysisTaskSE(name),\r
84 fPIDResponse(0x0),\r
85 fV0cuts(0x0),\r
86 fV0electrons(0x0),\r
87 fV0pions(0x0),\r
88 fV0kaons(0x0),\r
89 fV0protons(0x0),\r
90 fListQA(0x0),\r
91 fListQAits(0x0),\r
92 fListQAitsSA(0x0),\r
93 fListQAitsPureSA(0x0),\r
94 fListQAtpc(0x0),\r
95 fListQAtrd(0x0),\r
96 fListQAtof(0x0),\r
97 fListQAt0(0x0),\r
98 fListQAemcal(0x0),\r
99 fListQAhmpid(0x0),\r
100 fListQAtofhmpid(0x0),\r
101 fListQAtpctof(0x0),\r
102 fListQAV0(0x0),\r
103 fListQAinfo(0x0)\r
104 {\r
105   //\r
106   // Default constructor\r
107   //\r
108   DefineInput(0,TChain::Class());\r
109   DefineOutput(1,TList::Class());\r
110 }\r
111 \r
112 //______________________________________________________________________________\r
113 AliAnalysisTaskPIDqa::~AliAnalysisTaskPIDqa()\r
114 {\r
115   //\r
116   // Destructor\r
117   //\r
118 \r
119   delete fV0cuts;\r
120   delete fV0electrons;\r
121   delete fV0pions;\r
122   delete fV0kaons;\r
123   delete fV0protons;\r
124 \r
125   if (!AliAnalysisManager::GetAnalysisManager()->IsProofMode()) delete fListQA;\r
126 }\r
127 \r
128 //______________________________________________________________________________\r
129 void AliAnalysisTaskPIDqa::UserCreateOutputObjects()\r
130 {\r
131   //\r
132   // Create the output QA objects\r
133   //\r
134 \r
135   AliLog::SetClassDebugLevel("AliAnalysisTaskPIDqa",10);\r
136 \r
137   //input hander\r
138   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();\r
139   AliInputEventHandler *inputHandler=dynamic_cast<AliInputEventHandler*>(man->GetInputEventHandler());\r
140   if (!inputHandler) AliFatal("Input handler needed");\r
141 \r
142   //pid response object\r
143   fPIDResponse=inputHandler->GetPIDResponse();\r
144   if (!fPIDResponse) AliError("PIDResponse object was not created");\r
145   \r
146   // V0 Kine cuts \r
147   fV0cuts = new AliESDv0KineCuts;\r
148  \r
149   // V0 PID Obj arrays\r
150   fV0electrons = new TObjArray;\r
151   fV0pions     = new TObjArray;\r
152   fV0kaons     = new TObjArray;\r
153   fV0protons   = new TObjArray;\r
154 \r
155   //\r
156   fListQA=new TList;\r
157   fListQA->SetOwner();\r
158   \r
159   fListQAits=new TList;\r
160   fListQAits->SetOwner();\r
161   fListQAits->SetName("ITS");\r
162 \r
163   fListQAitsSA=new TList;\r
164   fListQAitsSA->SetOwner();\r
165   fListQAitsSA->SetName("ITS_SA");\r
166 \r
167   fListQAitsPureSA=new TList;\r
168   fListQAitsPureSA->SetOwner();\r
169   fListQAitsPureSA->SetName("ITS_PureSA");\r
170 \r
171   fListQAtpc=new TList;\r
172   fListQAtpc->SetOwner();\r
173   fListQAtpc->SetName("TPC");\r
174   \r
175   fListQAtrd=new TList;\r
176   fListQAtrd->SetOwner();\r
177   fListQAtrd->SetName("TRD");\r
178   \r
179   fListQAtof=new TList;\r
180   fListQAtof->SetOwner();\r
181   fListQAtof->SetName("TOF");\r
182 \r
183   fListQAt0=new TList;\r
184   fListQAt0->SetOwner();\r
185   fListQAt0->SetName("T0");\r
186   \r
187   fListQAemcal=new TList;\r
188   fListQAemcal->SetOwner();\r
189   fListQAemcal->SetName("EMCAL");\r
190   \r
191   fListQAhmpid=new TList;\r
192   fListQAhmpid->SetOwner();\r
193   fListQAhmpid->SetName("HMPID");\r
194   \r
195   fListQAtpctof=new TList;\r
196   fListQAtpctof->SetOwner();\r
197   fListQAtpctof->SetName("TPC_TOF");\r
198 \r
199   fListQAtofhmpid=new TList;\r
200   fListQAtofhmpid->SetOwner();\r
201   fListQAtofhmpid->SetName("TOF_HMPID");\r
202   \r
203   fListQAV0=new TList;\r
204   fListQAV0->SetOwner();\r
205   fListQAV0->SetName("V0decay");\r
206 \r
207   fListQAinfo=new TList;\r
208   fListQAinfo->SetOwner();\r
209   fListQAinfo->SetName("QAinfo");\r
210   \r
211   fListQA->Add(fListQAits);\r
212   fListQA->Add(fListQAitsSA);\r
213   fListQA->Add(fListQAitsPureSA);\r
214   fListQA->Add(fListQAtpc);\r
215   fListQA->Add(fListQAtrd);\r
216   fListQA->Add(fListQAtof);\r
217   fListQA->Add(fListQAt0);\r
218   fListQA->Add(fListQAemcal);\r
219   fListQA->Add(fListQAhmpid);\r
220   fListQA->Add(fListQAtpctof);\r
221   fListQA->Add(fListQAtofhmpid);\r
222   fListQA->Add(fListQAV0);\r
223   fListQA->Add(fListQAinfo);\r
224 \r
225   SetupITSqa();\r
226   SetupTPCqa();\r
227   SetupTRDqa();\r
228   SetupTOFqa();\r
229   SetupT0qa();\r
230   SetupEMCALqa();\r
231   SetupHMPIDqa();\r
232   SetupTPCTOFqa();\r
233   SetupTOFHMPIDqa();\r
234   SetupV0qa();\r
235   SetupQAinfo();\r
236   \r
237   PostData(1,fListQA);\r
238 }\r
239 \r
240 \r
241 //______________________________________________________________________________\r
242 void AliAnalysisTaskPIDqa::UserExec(Option_t */*option*/)\r
243 {\r
244   //\r
245   // Setup the PID response functions and fill the QA histograms\r
246   //\r
247 \r
248   AliVEvent *event=InputEvent();\r
249   if (!event||!fPIDResponse) return;\r
250 \r
251   // Start with the V0 task (only possible for ESDs?)\r
252   FillV0PIDlist();\r
253   \r
254   FillITSqa();\r
255   FillTPCqa();\r
256   FillTRDqa();\r
257   FillTOFqa();\r
258   FillEMCALqa();\r
259   FillHMPIDqa();\r
260   FillT0qa();\r
261   \r
262   //combined detector QA\r
263   FillTPCTOFqa();\r
264   FillTOFHMPIDqa();\r
265   \r
266   // Clear the V0 PID arrays\r
267   ClearV0PIDlist();\r
268 \r
269   //QA info\r
270   FillQAinfo();\r
271   \r
272   PostData(1,fListQA);\r
273 }\r
274 \r
275 //______________________________________________________________________________\r
276 void  AliAnalysisTaskPIDqa::FillV0PIDlist(){\r
277 \r
278   //\r
279   // Fill the PID object arrays holding the pointers to identified particle tracks\r
280   //\r
281 \r
282   // Dynamic cast to ESD events (DO NOTHING for AOD events)\r
283   AliESDEvent *event = dynamic_cast<AliESDEvent *>(InputEvent());\r
284   if ( !event )  return;\r
285   \r
286   if(TString(event->GetBeamType())=="Pb-Pb" || TString(event->GetBeamType())=="A-A"){\r
287     fV0cuts->SetMode(AliESDv0KineCuts::kPurity,AliESDv0KineCuts::kPbPb); \r
288   }\r
289   else{\r
290     fV0cuts->SetMode(AliESDv0KineCuts::kPurity,AliESDv0KineCuts::kPP); \r
291   }\r
292 \r
293   // V0 selection\r
294   // set event\r
295   fV0cuts->SetEvent(event);\r
296 \r
297   // loop over V0 particles\r
298   for(Int_t iv0=0; iv0<event->GetNumberOfV0s();iv0++){\r
299 \r
300     AliESDv0 *v0 = (AliESDv0 *) event->GetV0(iv0);\r
301  \r
302     if(!v0) continue;\r
303     if(v0->GetOnFlyStatus()) continue; \r
304   \r
305     // Get the particle selection \r
306     Bool_t foundV0 = kFALSE;\r
307     Int_t pdgV0, pdgP, pdgN;\r
308 \r
309     foundV0 = fV0cuts->ProcessV0(v0, pdgV0, pdgP, pdgN);\r
310     if(!foundV0) continue;\r
311     \r
312     Int_t iTrackP = v0->GetPindex();  // positive track\r
313     Int_t iTrackN = v0->GetNindex();  // negative track\r
314 \r
315     // v0 Armenteros plot (QA)\r
316     Float_t armVar[2] = {0.0,0.0};\r
317     fV0cuts->Armenteros(v0, armVar);\r
318 \r
319     TH2 *h=(TH2*)fListQAV0->At(0);\r
320     if (!h) continue;\r
321     h->Fill(armVar[0],armVar[1]);\r
322 \r
323     // fill the Object arrays\r
324     // positive particles\r
325     if( pdgP == -11){\r
326       fV0electrons->Add((AliVTrack*)event->GetTrack(iTrackP));\r
327     }\r
328     else if( pdgP == 211){\r
329       fV0pions->Add((AliVTrack*)event->GetTrack(iTrackP));\r
330     }\r
331     else if( pdgP == 321){\r
332       fV0kaons->Add((AliVTrack*)event->GetTrack(iTrackP));\r
333     }\r
334     else if( pdgP == 2212){\r
335       fV0protons->Add((AliVTrack*)event->GetTrack(iTrackP));\r
336     }\r
337 \r
338     // negative particles\r
339     if( pdgN == 11){\r
340       fV0electrons->Add((AliVTrack*)event->GetTrack(iTrackN));\r
341     }\r
342     else if( pdgN == -211){\r
343       fV0pions->Add((AliVTrack*)event->GetTrack(iTrackN));\r
344     }\r
345     else if( pdgN == -321){\r
346       fV0kaons->Add((AliVTrack*)event->GetTrack(iTrackN));\r
347     }\r
348     else if( pdgN == -2212){\r
349       fV0protons->Add((AliVTrack*)event->GetTrack(iTrackN));\r
350     }\r
351   \r
352 \r
353   }\r
354 }\r
355 //______________________________________________________________________________\r
356 void  AliAnalysisTaskPIDqa::ClearV0PIDlist(){\r
357 \r
358   //\r
359   // Clear the PID object arrays\r
360   //\r
361 \r
362   fV0electrons->Clear();\r
363   fV0pions->Clear();\r
364   fV0kaons->Clear();\r
365   fV0protons->Clear();\r
366 \r
367 }\r
368 //______________________________________________________________________________\r
369 void AliAnalysisTaskPIDqa::FillITSqa()\r
370 {\r
371   //\r
372   // Fill PID qa histograms for the ITS\r
373   //\r
374 \r
375   AliVEvent *event=InputEvent();\r
376   \r
377   Int_t ntracks=event->GetNumberOfTracks();\r
378   for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
379     AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
380     ULong_t status=track->GetStatus();\r
381     // not that nice. status bits not in virtual interface\r
382     // ITS refit + ITS pid selection\r
383     if (!( ( (status & AliVTrack::kITSrefit)==AliVTrack::kITSrefit ) ||\r
384            ! ( (status & AliVTrack::kITSpid  )==AliVTrack::kITSpid   ) )) continue;\r
385     Double_t mom=track->P();\r
386     \r
387     TList *theList = 0x0;\r
388     if(( (status & AliVTrack::kTPCin)==AliVTrack::kTPCin )){\r
389       //ITS+TPC tracks\r
390       theList=fListQAits;\r
391     }else{\r
392       if(!( (status & AliVTrack::kITSpureSA)==AliVTrack::kITSpureSA )){ \r
393         //ITS Standalone tracks\r
394         theList=fListQAitsSA;\r
395       }else{\r
396         //ITS Pure Standalone tracks\r
397         theList=fListQAitsPureSA;\r
398       }\r
399     }\r
400     \r
401     \r
402     for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
403       TH2 *h=(TH2*)theList->At(ispecie);\r
404       if (!h) continue;\r
405       Double_t nSigma=fPIDResponse->NumberOfSigmasITS(track, (AliPID::EParticleType)ispecie);\r
406       h->Fill(mom,nSigma);\r
407     }\r
408     TH2 *h=(TH2*)theList->At(AliPID::kSPECIESC);\r
409     if (h) {\r
410       Double_t sig=track->GetITSsignal();\r
411       h->Fill(mom,sig);\r
412     }\r
413   }\r
414 }\r
415 \r
416 //______________________________________________________________________________\r
417 void AliAnalysisTaskPIDqa::FillTPCqa()\r
418 {\r
419   //\r
420   // Fill PID qa histograms for the TPC\r
421   //\r
422   \r
423   AliVEvent *event=InputEvent();\r
424   \r
425   Int_t ntracks=event->GetNumberOfTracks();\r
426   for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
427     AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
428     \r
429     //\r
430     //basic track cuts\r
431     //\r
432     ULong_t status=track->GetStatus();\r
433     // not that nice. status bits not in virtual interface\r
434     // TPC refit + ITS refit + TPC pid\r
435     if (!( (status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
436         !( (status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ) continue;\r
437 \r
438     // The TPC pid cut removes the light nuclei (>5 sigma from proton line)\r
439     //||        !( (status & AliVTrack::kTPCpid  ) == AliVTrack::kTPCpid  )\r
440     Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
441     Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
442     if (track->GetTPCNclsF()>0) {\r
443       ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
444     }\r
445     \r
446     if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
447     \r
448     Double_t mom=track->GetTPCmomentum();\r
449     // the default scenario\r
450     for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
451       TH2 *h=(TH2*)fListQAtpc->At(ispecie);\r
452       if (!h) continue;\r
453       Double_t nSigma=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie);\r
454       h->Fill(mom,nSigma);\r
455     }\r
456     // the "hybrid" scenario\r
457     for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
458       TH2 *h=(TH2*)fListQAtpc->At(ispecie+AliPID::kSPECIESC);\r
459       if (!h) continue;\r
460       Double_t nSigma=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie, AliTPCPIDResponse::kdEdxHybrid);\r
461       h->Fill(mom,nSigma);\r
462     }\r
463     \r
464     // the "OROC" scenario\r
465     for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
466       TH2 *h=(TH2*)fListQAtpc->At(ispecie+2*AliPID::kSPECIESC);\r
467       if (!h) continue;\r
468       Double_t nSigma=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie, AliTPCPIDResponse::kdEdxOROC);\r
469       //TSpline3* spline = fPIDResponse->GetTPCResponse().GetCurrentResponseFunction();\r
470       //std::cout<<ispecie<<" "<<nSigma<<" phi:"<<track->Phi()<<". "<<std::endl;\r
471       //if (spline) {cout<<spline->GetName()<<endl;}\r
472       //else {cout<<"NULL spline"<<endl;}\r
473       h->Fill(mom,nSigma);\r
474     }\r
475     \r
476     TH2 *h=(TH2*)fListQAtpc->At(3*AliPID::kSPECIESC);\r
477 \r
478     if (h) {\r
479       Double_t sig=track->GetTPCsignal();\r
480       h->Fill(mom,sig);\r
481     }\r
482   }\r
483 }\r
484 \r
485 //______________________________________________________________________________\r
486 void AliAnalysisTaskPIDqa::FillTRDqa()\r
487 {\r
488   //\r
489   // Fill PID qa histograms for the TRD\r
490   //\r
491   AliVEvent *event=InputEvent();\r
492   Int_t ntracks = event->GetNumberOfTracks();\r
493   for(Int_t itrack = 0; itrack <  ntracks; itrack++){\r
494     AliVTrack *track = (AliVTrack *)event->GetTrack(itrack);\r
495 \r
496     //\r
497     //basic track cuts\r
498     //\r
499     ULong_t status=track->GetStatus();\r
500     // not that nice. status bits not in virtual interface\r
501     // TPC refit + ITS refit + TPC pid + TRD out\r
502     if (!( (status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
503         !( (status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||\r
504 //         !( (status & AliVTrack::kTPCpid  ) == AliVTrack::kTPCpid  ) || //removes light nuclei. So it is out for the moment\r
505         !( (status & AliVTrack::kTRDout  ) == AliVTrack::kTRDout  )) continue;\r
506     \r
507     Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
508     Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
509     if (track->GetTPCNclsF()>0) {\r
510       ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
511     }\r
512     \r
513     if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
514 \r
515     Double_t likelihoods[AliPID::kSPECIES];\r
516     if(fPIDResponse->ComputeTRDProbability(track, AliPID::kSPECIES, likelihoods) != AliPIDResponse::kDetPidOk) continue;\r
517     Int_t ntracklets = 0;\r
518     Double_t momentum = -1.;\r
519     for(Int_t itl = 0; itl < 6; itl++)\r
520       if(track->GetTRDmomentum(itl) > 0.){\r
521         ntracklets++;\r
522         if(momentum < 0) momentum = track->GetTRDmomentum(itl);\r
523     } \r
524     for(Int_t ispecie = 0; ispecie < AliPID::kSPECIES; ispecie++){\r
525       TH2F *hLike = (TH2F *)fListQAtrd->At(ntracklets*AliPID::kSPECIES+ispecie);\r
526       if (hLike) hLike->Fill(momentum,likelihoods[ispecie]);\r
527     }\r
528   }\r
529 }\r
530 \r
531 //______________________________________________________________________________\r
532 void AliAnalysisTaskPIDqa::FillTOFqa()\r
533 {\r
534   //\r
535   // Fill TOF information\r
536   //\r
537   AliVEvent *event=InputEvent();\r
538 \r
539   Int_t ntracks=event->GetNumberOfTracks();\r
540   Int_t tracksAtTof = 0;\r
541   for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
542     AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
543 \r
544     //\r
545     //basic track cuts\r
546     //\r
547     ULong_t status=track->GetStatus();\r
548     // TPC refit + ITS refit +\r
549     // TOF out + kTIME\r
550     // kTIME\r
551     // (we don't use kTOFmismatch because it depends on TPC and kTOFpid because it prevents light nuclei\r
552     if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
553         !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||\r
554         !((status & AliVTrack::kTOFout  ) == AliVTrack::kTOFout  ) ||\r
555         //        !((status & AliVTrack::kTOFpid  ) == AliVTrack::kTOFpid  ) ||\r
556         !((status & AliVTrack::kTIME    ) == AliVTrack::kTIME    ) ) continue;\r
557 \r
558     Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
559     Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
560     if (track->GetTPCNclsF()>0) {\r
561       ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
562     }\r
563 \r
564     if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
565 \r
566     tracksAtTof++;\r
567 \r
568     Double_t mom=track->P();\r
569 \r
570     for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
571       TH2 *h=(TH2*)fListQAtof->At(ispecie);\r
572       if (!h) continue;\r
573       Double_t nSigma=fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)ispecie);\r
574       h->Fill(mom,nSigma);\r
575     }\r
576 \r
577     TH2 *h=(TH2*)fListQAtof->FindObject("hSigP_TOF");\r
578     if (h) {\r
579       Double_t sig=track->GetTOFsignal()/1000.;\r
580       h->Fill(mom,sig);\r
581     }\r
582 \r
583     Int_t mask = fPIDResponse->GetTOFResponse().GetStartTimeMask(mom);\r
584     ((TH1F*)fListQAtof->FindObject("hStartTimeMask_TOF"))->Fill((Double_t)(mask+0.5));\r
585 \r
586     if (mom >= 0.75 && mom <= 1.25 ) {\r
587       Double_t nsigma= fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)AliPID::kPion);\r
588       if (mask == 0) {\r
589         ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-Fill"))->Fill(nsigma);\r
590       } else if (mask == 1) {\r
591         ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-TOF"))->Fill(nsigma);\r
592       } else if ( (mask == 2) || (mask == 4) || (mask == 6) ) {\r
593         ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-T0"))->Fill(nsigma);\r
594       } else {\r
595         ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-Best"))->Fill(nsigma);\r
596       }\r
597       if (mask & 0x1) { //at least TOF-T0 present\r
598         Double_t delta=0;\r
599         (void)fPIDResponse->GetSignalDelta((AliPIDResponse::EDetector)AliPIDResponse::kTOF,track,(AliPID::EParticleType)AliPID::kPion,delta);\r
600         ((TH1F*)fListQAtof->FindObject("hDelta_TOF_Pion"))->Fill(delta);\r
601       }\r
602     }\r
603 \r
604     Double_t res = (Double_t)fPIDResponse->GetTOFResponse().GetStartTimeRes(mom);\r
605     ((TH1F*)fListQAtof->FindObject("hStartTimeRes_TOF"))->Fill(res);\r
606 \r
607     Double_t startTimeT0 = event->GetT0TOF(0);\r
608     if (startTimeT0 < 90000) ((TH1F*)fListQAtof->FindObject("hStartTimeAC_T0"))->Fill(startTimeT0);\r
609     else {\r
610       startTimeT0 = event->GetT0TOF(1);\r
611       if (startTimeT0 < 90000) ((TH1F*)fListQAtof->FindObject("hStartTimeA_T0"))->Fill(startTimeT0);\r
612       startTimeT0 = event->GetT0TOF(2);\r
613       if (startTimeT0 < 90000) ((TH1F*)fListQAtof->FindObject("hStartTimeC_T0"))->Fill(startTimeT0);\r
614     }\r
615   }\r
616   if (tracksAtTof > 0) {\r
617     ((TH1F* )fListQAtof->FindObject("hnTracksAt_TOF"))->Fill(tracksAtTof);\r
618     Int_t mask = fPIDResponse->GetTOFResponse().GetStartTimeMask(5.);\r
619     if (mask & 0x1) ((TH1F*)fListQAtof->FindObject("hT0MakerEff"))->Fill(tracksAtTof);\r
620   }\r
621 }\r
622 \r
623 //______________________________________________________________________________\r
624 void AliAnalysisTaskPIDqa::FillT0qa()\r
625 {\r
626   //\r
627   // Fill TOF information\r
628   //\r
629   AliVEvent *event=InputEvent();\r
630 \r
631   Int_t ntracks=event->GetNumberOfTracks();\r
632 \r
633   Int_t tracksAtT0 = 0;\r
634 \r
635   for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
636     AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
637 \r
638     //\r
639     //basic track cuts\r
640     //\r
641     ULong_t status=track->GetStatus();\r
642     // TPC refit + ITS refit +\r
643     if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
644         !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ) continue;\r
645     Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
646     Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
647     if (track->GetTPCNclsF()>0) {\r
648       ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
649     }\r
650     if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
651 \r
652     tracksAtT0++;\r
653   }\r
654 \r
655   Bool_t t0A = kFALSE;\r
656   Bool_t t0C = kFALSE;\r
657   Bool_t t0And = kFALSE;\r
658   Double_t startTimeT0 = event->GetT0TOF(0);     // AND\r
659   if (startTimeT0 < 90000) {\r
660     t0And = kTRUE;\r
661     ((TH1F*)fListQAt0->FindObject("hStartTimeAC_T0"))->Fill(startTimeT0);\r
662     }\r
663   startTimeT0 = event->GetT0TOF(1);             // T0A \r
664   if (startTimeT0 < 90000) {\r
665     t0A = kTRUE;\r
666     ((TH1F*)fListQAt0->FindObject("hStartTimeA_T0"))->Fill(startTimeT0);\r
667     \r
668   }\r
669   startTimeT0 = event->GetT0TOF(2);             // T0C \r
670   if (startTimeT0 < 90000) {\r
671     t0C = kTRUE;\r
672     ((TH1F*)fListQAt0->FindObject("hStartTimeC_T0"))->Fill(startTimeT0);\r
673   }\r
674   \r
675   ((TH1F* )fListQAt0->FindObject("hnTracksAt_T0"))->Fill(tracksAtT0);\r
676   if (t0A) ((TH1F*)fListQAt0->FindObject("hT0AEff"))->Fill(tracksAtT0);\r
677   if (t0C) ((TH1F*)fListQAt0->FindObject("hT0CEff"))->Fill(tracksAtT0);\r
678   if (t0And) ((TH1F*)fListQAt0->FindObject("hT0AndEff"))->Fill(tracksAtT0);\r
679   if (t0A || t0C) ((TH1F*)fListQAt0->FindObject("hT0OrEff"))->Fill(tracksAtT0);\r
680 }\r
681 \r
682 \r
683 //______________________________________________________________________________\r
684 void AliAnalysisTaskPIDqa::FillEMCALqa()\r
685 {\r
686   //\r
687   // Fill PID qa histograms for the EMCAL\r
688   //\r
689 \r
690   AliVEvent *event=InputEvent();\r
691   \r
692   Int_t ntracks=event->GetNumberOfTracks();\r
693   for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
694     AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
695     \r
696     //\r
697     //basic track cuts\r
698     //\r
699     ULong_t status=track->GetStatus();\r
700     // not that nice. status bits not in virtual interface\r
701     if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;\r
702 \r
703     Double_t pt=track->Pt();\r
704    \r
705     //EMCAL nSigma (only for electrons at the moment)\r
706     TH2 *h=(TH2*)fListQAemcal->At(0);\r
707     if (!h) continue;\r
708     Double_t nSigma=fPIDResponse->NumberOfSigmasEMCAL(track, (AliPID::EParticleType)0);\r
709     h->Fill(pt,nSigma);\r
710     \r
711   }\r
712 \r
713    //EMCAL signal (E/p vs. pT) for electrons from V0\r
714   for(Int_t itrack = 0; itrack < fV0electrons->GetEntries(); itrack++){\r
715     AliVTrack *track=(AliVTrack*)fV0electrons->At(itrack);\r
716 \r
717     //\r
718     //basic track cuts\r
719     //\r
720     ULong_t status=track->GetStatus();\r
721     // not that nice. status bits not in virtual interface\r
722     if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;\r
723 \r
724     Double_t pt=track->Pt();\r
725 \r
726     TH2 *h=(TH2*)fListQAemcal->At(1);\r
727     if (h) {\r
728 \r
729       Int_t nMatchClus = track->GetEMCALcluster();\r
730       Double_t mom     = track->P();\r
731       Double_t eop     = -1.;\r
732 \r
733       if(nMatchClus > -1){\r
734     \r
735         AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);\r
736 \r
737         if(matchedClus){\r
738 \r
739           // matched cluster is EMCAL\r
740           if(matchedClus->IsEMCAL()){\r
741 \r
742             Double_t fClsE       = matchedClus->E();\r
743             eop                  = fClsE/mom;\r
744 \r
745             h->Fill(pt,eop);\r
746 \r
747           }\r
748         }\r
749       }\r
750     }\r
751   }\r
752 \r
753    //EMCAL signal (E/p vs. pT) for pions from V0\r
754   for(Int_t itrack = 0; itrack < fV0pions->GetEntries(); itrack++){\r
755     AliVTrack *track=(AliVTrack*)fV0pions->At(itrack);\r
756 \r
757     //\r
758     //basic track cuts\r
759     //\r
760     ULong_t status=track->GetStatus();\r
761     // not that nice. status bits not in virtual interface\r
762     if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;\r
763 \r
764     Double_t pt=track->Pt();\r
765 \r
766     TH2 *h=(TH2*)fListQAemcal->At(2);\r
767     if (h) {\r
768 \r
769       Int_t nMatchClus = track->GetEMCALcluster();\r
770       Double_t mom     = track->P();\r
771       Double_t eop     = -1.;\r
772 \r
773       if(nMatchClus > -1){\r
774     \r
775         AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);\r
776 \r
777         if(matchedClus){\r
778 \r
779           // matched cluster is EMCAL\r
780           if(matchedClus->IsEMCAL()){\r
781 \r
782             Double_t fClsE       = matchedClus->E();\r
783             eop                  = fClsE/mom;\r
784 \r
785             h->Fill(pt,eop);\r
786 \r
787           }\r
788         }\r
789       }\r
790     }\r
791   }\r
792 \r
793    //EMCAL signal (E/p vs. pT) for protons from V0\r
794   for(Int_t itrack = 0; itrack < fV0protons->GetEntries(); itrack++){\r
795     AliVTrack *track=(AliVTrack*)fV0protons->At(itrack);\r
796 \r
797     //\r
798     //basic track cuts\r
799     //\r
800     ULong_t status=track->GetStatus();\r
801     // not that nice. status bits not in virtual interface\r
802     if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;\r
803 \r
804     Double_t pt=track->Pt();\r
805 \r
806     TH2 *hP=(TH2*)fListQAemcal->At(3);\r
807     TH2 *hAP=(TH2*)fListQAemcal->At(4);\r
808     if (hP && hAP) {\r
809 \r
810       Int_t nMatchClus = track->GetEMCALcluster();\r
811       Double_t mom     = track->P();\r
812       Int_t charge     = track->Charge();             \r
813       Double_t eop     = -1.;\r
814 \r
815       if(nMatchClus > -1){\r
816     \r
817         AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);\r
818 \r
819         if(matchedClus){\r
820 \r
821           // matched cluster is EMCAL\r
822           if(matchedClus->IsEMCAL()){\r
823 \r
824             Double_t fClsE       = matchedClus->E();\r
825             eop                  = fClsE/mom;\r
826 \r
827             if(charge > 0)      hP->Fill(pt,eop);\r
828             else if(charge < 0) hAP->Fill(pt,eop);\r
829 \r
830           }\r
831         }\r
832       }\r
833     }\r
834   }\r
835 \r
836 }\r
837 \r
838 \r
839 //______________________________________________________________________________\r
840 void AliAnalysisTaskPIDqa::FillHMPIDqa()\r
841 {\r
842   //\r
843   // Fill PID qa histograms for the HMPID\r
844   //\r
845   \r
846   AliVEvent *event=InputEvent();\r
847   \r
848   Int_t ntracks=event->GetNumberOfTracks();\r
849   for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
850     AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
851     \r
852     //\r
853     //basic track cuts\r
854     //\r
855     ULong_t status=track->GetStatus();\r
856     // not that nice. status bits not in virtual interface\r
857     // TPC refit + ITS refit +\r
858     // TOF out + TOFpid +\r
859     // kTIME\r
860     if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
861         !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ) continue;\r
862 \r
863     Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
864     Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
865     if (track->GetTPCNclsF()>0) {\r
866       ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
867     }\r
868 \r
869     if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
870     \r
871     Double_t mom = track->P();\r
872     Double_t ckovAngle = track->GetHMPIDsignal();\r
873     \r
874     TH1F *hThetavsMom = (TH1F*)fListQAhmpid->At(0);;\r
875     \r
876     hThetavsMom->Fill(mom,ckovAngle);    \r
877   \r
878   }\r
879 }\r
880 //______________________________________________________________________________\r
881 void AliAnalysisTaskPIDqa::FillTOFHMPIDqa()\r
882 {\r
883   //\r
884   // Fill PID qa histograms for the HMPID\r
885   //\r
886   \r
887   AliVEvent *event=InputEvent();\r
888   \r
889   Int_t ntracks=event->GetNumberOfTracks();\r
890   for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
891     AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
892     \r
893     //\r
894     //basic track cuts\r
895     //\r
896     ULong_t status=track->GetStatus();\r
897     // not that nice. status bits not in virtual interface\r
898     // TPC refit + ITS refit +\r
899     // TOF out + TOFpid +\r
900     // kTIME\r
901     if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
902         !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||\r
903         !((status & AliVTrack::kTOFout  ) == AliVTrack::kTOFout  ) ||\r
904         !((status & AliVTrack::kTOFpid  ) == AliVTrack::kTOFpid  ) ||\r
905         !((status & AliVTrack::kTIME    ) == AliVTrack::kTIME    ) ) continue;\r
906 \r
907     Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
908     Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
909     if (track->GetTPCNclsF()>0) {\r
910       ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
911     }\r
912 \r
913     if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
914     \r
915     Double_t mom = track->P();\r
916     Double_t ckovAngle = track->GetHMPIDsignal();\r
917     \r
918     Double_t nSigmaTOF[3]; \r
919     TH1F *h[3];\r
920     \r
921     for (Int_t ispecie=2; ispecie<5; ++ispecie){\r
922       //TOF nSigma\r
923       nSigmaTOF[ispecie-2]=fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)ispecie);\r
924       h[ispecie-2] = (TH1F*)fListQAtofhmpid->At(ispecie-2);}\r
925       \r
926     if(TMath::Abs(nSigmaTOF[0])<2)                                                              h[0]->Fill(mom,ckovAngle);\r
927     \r
928     if(TMath::Abs(nSigmaTOF[1])<2 && TMath::Abs(nSigmaTOF[0])>3)                                h[1]->Fill(mom,ckovAngle);\r
929 \r
930     if(TMath::Abs(nSigmaTOF[2])<2 && TMath::Abs(nSigmaTOF[1])>3 && TMath::Abs(nSigmaTOF[0])>3)  h[2]->Fill(mom,ckovAngle);\r
931       \r
932   }\r
933   \r
934 }\r
935 \r
936 //______________________________________________________________________________\r
937 void AliAnalysisTaskPIDqa::FillTPCTOFqa()\r
938 {\r
939   //\r
940   // Fill PID qa histograms for the TOF\r
941   //   Here also the TPC histograms after TOF selection are filled\r
942   //\r
943 \r
944   AliVEvent *event=InputEvent();\r
945 \r
946   Int_t ntracks=event->GetNumberOfTracks();\r
947   for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
948     AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
949 \r
950     //\r
951     //basic track cuts\r
952     //\r
953     ULong_t status=track->GetStatus();\r
954     // not that nice. status bits not in virtual interface\r
955     // TPC refit + ITS refit +\r
956     // TOF out + TOFpid +\r
957     // kTIME\r
958     if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
959         !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||\r
960 //         !( (status & AliVTrack::kTPCpid  ) == AliVTrack::kTPCpid ) || //removes light nuclei, so it is out for the moment\r
961         !((status & AliVTrack::kTOFout  ) == AliVTrack::kTOFout  ) ||\r
962         !((status & AliVTrack::kTOFpid  ) == AliVTrack::kTOFpid  ) ||\r
963         !((status & AliVTrack::kTIME    ) == AliVTrack::kTIME    ) ) continue;\r
964 \r
965     Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
966     Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
967     if (track->GetTPCNclsF()>0) {\r
968       ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
969     }\r
970 \r
971     if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
972 \r
973 \r
974     Double_t mom=track->P();\r
975     Double_t momTPC=track->GetTPCmomentum();\r
976 \r
977     for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
978       //TOF nSigma\r
979       Double_t nSigmaTOF=fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)ispecie);\r
980       Double_t nSigmaTPC=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie);\r
981 \r
982       //TPC after TOF cut\r
983       TH2 *h=(TH2*)fListQAtpctof->At(ispecie);\r
984       if (h && TMath::Abs(nSigmaTOF)<3.) h->Fill(momTPC,nSigmaTPC);\r
985 \r
986       //TOF after TPC cut\r
987       h=(TH2*)fListQAtpctof->At(ispecie+AliPID::kSPECIESC);\r
988       if (h && TMath::Abs(nSigmaTPC)<3.) h->Fill(mom,nSigmaTOF);\r
989 \r
990       //EMCAL after TOF and TPC cut\r
991       h=(TH2*)fListQAtpctof->At(ispecie+2*AliPID::kSPECIESC);\r
992       if (h && TMath::Abs(nSigmaTOF)<3. && TMath::Abs(nSigmaTPC)<3. ){\r
993 \r
994         Int_t nMatchClus = track->GetEMCALcluster();\r
995         Double_t pt      = track->Pt();\r
996         Double_t eop     = -1.;\r
997         \r
998         if(nMatchClus > -1){\r
999           \r
1000           AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);\r
1001           \r
1002           if(matchedClus){\r
1003             \r
1004             // matched cluster is EMCAL\r
1005             if(matchedClus->IsEMCAL()){\r
1006               \r
1007               Double_t fClsE       = matchedClus->E();\r
1008               eop                  = fClsE/mom;\r
1009 \r
1010               h->Fill(pt,eop);\r
1011  \r
1012               \r
1013             }\r
1014           }\r
1015         }\r
1016       }\r
1017     }\r
1018   }\r
1019 }\r
1020 \r
1021 //_____________________________________________________________________________\r
1022 void AliAnalysisTaskPIDqa::FillQAinfo()\r
1023 {\r
1024   //\r
1025   // Fill the QA information\r
1026   //\r
1027 \r
1028 \r
1029   //TPC QA info\r
1030   TObjArray *arrTPC=static_cast<TObjArray*>(fListQAinfo->At(0));\r
1031   if (fPIDResponse && arrTPC){\r
1032     AliTPCPIDResponse &tpcResp=fPIDResponse->GetTPCResponse();\r
1033     // fill spline names\r
1034     if (!arrTPC->UncheckedAt(0)){\r
1035       \r
1036       TObjArray *arrTPCsplineNames=new TObjArray(AliPID::kSPECIESC);\r
1037       arrTPCsplineNames->SetOwner();\r
1038       arrTPCsplineNames->SetName("TPC_spline_names");\r
1039       arrTPC->AddAt(arrTPCsplineNames,0);\r
1040       \r
1041       for (Int_t iresp=0; iresp<AliPID::kSPECIESC; ++iresp){\r
1042         const TObject *o=tpcResp.GetResponseFunction((AliPID::EParticleType)iresp);\r
1043         if (!o) continue;\r
1044         arrTPCsplineNames->Add(new TObjString(Form("%02d: %s",iresp, o->GetName())));\r
1045       }\r
1046     }\r
1047 \r
1048     // tpc response config\r
1049     if (!arrTPC->UncheckedAt(1)){\r
1050       \r
1051       TObjArray *arrTPCconfigInfo=new TObjArray;\r
1052       arrTPCconfigInfo->SetOwner();\r
1053       arrTPCconfigInfo->SetName("TPC_config_info");\r
1054       arrTPC->AddAt(arrTPCconfigInfo,1);\r
1055 \r
1056       TObjString *ostr=0x0;\r
1057       ostr=new TObjString;\r
1058       ostr->String().Form("Eta Corr map: %s", tpcResp.GetEtaCorrMap()?tpcResp.GetEtaCorrMap()->GetName():"none");\r
1059       arrTPCconfigInfo->Add(ostr);\r
1060 \r
1061       ostr=new TObjString;\r
1062       ostr->String().Form("Sigma Par map: %s", tpcResp.GetSigmaPar1Map()?tpcResp.GetSigmaPar1Map()->GetName():"none");\r
1063       arrTPCconfigInfo->Add(ostr);\r
1064 \r
1065       ostr=new TObjString;\r
1066       ostr->String().Form("MIP: %.2f", tpcResp.GetMIP());\r
1067       arrTPCconfigInfo->Add(ostr);\r
1068       \r
1069       ostr=new TObjString;\r
1070       ostr->String().Form("Res: Def %.3g (%.3g) : AllHigh %.3g (%.3g) : OROC high %.3g (%.3g)",\r
1071                           tpcResp.GetRes0(AliTPCPIDResponse::kDefault), tpcResp.GetResN2(AliTPCPIDResponse::kDefault),\r
1072                           tpcResp.GetRes0(AliTPCPIDResponse::kALLhigh), tpcResp.GetResN2(AliTPCPIDResponse::kALLhigh),\r
1073                           tpcResp.GetRes0(AliTPCPIDResponse::kOROChigh), tpcResp.GetResN2(AliTPCPIDResponse::kOROChigh)\r
1074                          );\r
1075       arrTPCconfigInfo->Add(ostr);\r
1076     }\r
1077   }\r
1078 }\r
1079 \r
1080 //______________________________________________________________________________\r
1081 void AliAnalysisTaskPIDqa::SetupITSqa()\r
1082 {\r
1083   //\r
1084   // Create the ITS qa objects\r
1085   //\r
1086   \r
1087   TVectorD *vX=MakeLogBinning(200,.1,30);\r
1088   \r
1089   //ITS+TPC tracks\r
1090   for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
1091     TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_ITS_%s",AliPID::ParticleName(ispecie)),\r
1092                               Form("ITS n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
1093                               vX->GetNrows()-1,vX->GetMatrixArray(),\r
1094                               200,-10,10);\r
1095     fListQAits->Add(hNsigmaP);\r
1096   }\r
1097   TH2F *hSig = new TH2F("hSigP_ITS",\r
1098                         "ITS signal vs. p;p [GeV]; ITS signal [arb. units]",\r
1099                         vX->GetNrows()-1,vX->GetMatrixArray(),\r
1100                         300,0,300);\r
1101   fListQAits->Add(hSig);\r
1102 \r
1103   //ITS Standalone tracks\r
1104   for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
1105     TH2F *hNsigmaPSA = new TH2F(Form("hNsigmaP_ITSSA_%s",AliPID::ParticleName(ispecie)),\r
1106                                 Form("ITS n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
1107                                 vX->GetNrows()-1,vX->GetMatrixArray(),\r
1108                                 200,-10,10);\r
1109     fListQAitsSA->Add(hNsigmaPSA);\r
1110   }\r
1111   TH2F *hSigSA = new TH2F("hSigP_ITSSA",\r
1112                           "ITS signal vs. p;p [GeV]; ITS signal [arb. units]",\r
1113                           vX->GetNrows()-1,vX->GetMatrixArray(),\r
1114                           300,0,300);\r
1115   fListQAitsSA->Add(hSigSA);\r
1116   \r
1117   //ITS Pure Standalone tracks\r
1118   for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
1119     TH2F *hNsigmaPPureSA = new TH2F(Form("hNsigmaP_ITSPureSA_%s",AliPID::ParticleName(ispecie)),\r
1120                                     Form("ITS n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
1121                                     vX->GetNrows()-1,vX->GetMatrixArray(),\r
1122                                     200,-10,10);\r
1123     fListQAitsPureSA->Add(hNsigmaPPureSA);\r
1124   }\r
1125   TH2F *hSigPureSA = new TH2F("hSigP_ITSPureSA",\r
1126                               "ITS signal vs. p;p [GeV]; ITS signal [arb. units]",\r
1127                               vX->GetNrows()-1,vX->GetMatrixArray(),\r
1128                               300,0,300);\r
1129   fListQAitsPureSA->Add(hSigPureSA);\r
1130   \r
1131   delete vX;  \r
1132 }\r
1133 \r
1134 //______________________________________________________________________________\r
1135 void AliAnalysisTaskPIDqa::SetupTPCqa()\r
1136 {\r
1137   //\r
1138   // Create the TPC qa objects\r
1139   //\r
1140   \r
1141   TVectorD *vX=MakeLogBinning(200,.1,30);\r
1142   \r
1143   for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
1144     TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_%s",AliPID::ParticleName(ispecie)),\r
1145                               Form("TPC n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
1146                               vX->GetNrows()-1,vX->GetMatrixArray(),\r
1147                               200,-10,10);\r
1148     fListQAtpc->Add(hNsigmaP);\r
1149   }\r
1150 \r
1151   // the "hybrid" scenario\r
1152   for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
1153     TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_%s_Hybrid",AliPID::ParticleName(ispecie)),\r
1154                               Form("TPC n#sigma %s vs. p (Hybrid gain scenario);p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
1155                               vX->GetNrows()-1,vX->GetMatrixArray(),\r
1156                               200,-10,10);\r
1157     fListQAtpc->Add(hNsigmaP);\r
1158   }\r
1159    \r
1160   // the "OROC high" scenario\r
1161   for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
1162     TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_%s_OROChigh",AliPID::ParticleName(ispecie)),\r
1163                               Form("TPC n#sigma %s vs. p (OROChigh gain scenario);p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
1164                               vX->GetNrows()-1,vX->GetMatrixArray(),\r
1165                               200,-10,10);\r
1166     fListQAtpc->Add(hNsigmaP);\r
1167   }\r
1168   \r
1169   \r
1170   \r
1171   TH2F *hSig = new TH2F("hSigP_TPC",\r
1172                         "TPC signal vs. p;p [GeV]; TPC signal [arb. units]",\r
1173                         vX->GetNrows()-1,vX->GetMatrixArray(),\r
1174                         300,0,300);\r
1175   fListQAtpc->Add(hSig); //3*AliPID::kSPECIESC\r
1176 \r
1177   delete vX;  \r
1178 }\r
1179 \r
1180 //______________________________________________________________________________\r
1181 void AliAnalysisTaskPIDqa::SetupTRDqa()\r
1182 {\r
1183   //\r
1184   // Create the TRD qa objects\r
1185   //\r
1186   TVectorD *vX=MakeLogBinning(200,.1,30);\r
1187   for(Int_t itl = 0; itl < 6; ++itl){\r
1188     for(Int_t ispecie = 0; ispecie < AliPID::kSPECIES; ispecie++){\r
1189       TH2F *hLikeP = new TH2F(Form("hLikeP_TRD_%dtls_%s", itl, AliPID::ParticleName(ispecie)),\r
1190                               Form("TRD Likelihood to be %s %s for tracks having %d %s; p (GeV/c); TRD %s Likelihood", ispecie == 0 ? "an" : "a", AliPID::ParticleName(ispecie), itl+1, itl == 0 ? "tracklet" : "tracklets", AliPID::ParticleName(ispecie)),\r
1191                               vX->GetNrows()-1, vX->GetMatrixArray(),\r
1192                               100, 0., 1.);\r
1193       fListQAtrd->Add(hLikeP);\r
1194     }\r
1195   }\r
1196   delete vX;\r
1197 }\r
1198 \r
1199 //______________________________________________________________________________\r
1200 void AliAnalysisTaskPIDqa::SetupTOFqa()\r
1201 {\r
1202   //\r
1203   // Create the TOF qa objects\r
1204   //\r
1205   \r
1206   TVectorD *vX=MakeLogBinning(200,.1,30);\r
1207 \r
1208   for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
1209     TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TOF_%s",AliPID::ParticleName(ispecie)),\r
1210                               Form("TOF n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
1211                               vX->GetNrows()-1,vX->GetMatrixArray(),\r
1212                               200,-10,10);\r
1213     fListQAtof->Add(hNsigmaP);\r
1214   }\r
1215 \r
1216   TH1F *hnSigT0Fill = new TH1F("hNsigma_TOF_Pion_T0-Fill","TOF n#sigma (Pion) T0-FILL [0.75-1.25. GeV/c]",200,-10,10);\r
1217   fListQAtof->Add(hnSigT0Fill);\r
1218   TH1F *hnSigT0T0 = new TH1F("hNsigma_TOF_Pion_T0-T0","TOF n#sigma (Pion) T0-T0 [0.75-1.25 GeV/c]",200,-10,10);\r
1219   fListQAtof->Add(hnSigT0T0);\r
1220   TH1F *hnSigT0TOF = new TH1F("hNsigma_TOF_Pion_T0-TOF","TOF n#sigma (Pion) T0-TOF [0.75-1.25 GeV/c]",200,-10,10);\r
1221   fListQAtof->Add(hnSigT0TOF);\r
1222   TH1F *hnSigT0Best = new TH1F("hNsigma_TOF_Pion_T0-Best","TOF n#sigma (Pion) T0-Best [0.75-1.25 GeV/c]",200,-10,10);\r
1223   fListQAtof->Add(hnSigT0Best);\r
1224   TH1F *hnDeltaPi = new TH1F("hDelta_TOF_Pion","DeltaT (Pion) [0.75-1.25 GeV/c]",50,-500,500);\r
1225   fListQAtof->Add(hnDeltaPi);\r
1226   \r
1227   TH2F *hSig = new TH2F("hSigP_TOF",\r
1228                         "TOF signal vs. p;p [GeV]; TOF signal [ns]",\r
1229                         vX->GetNrows()-1,vX->GetMatrixArray(),\r
1230                         300,0,30);\r
1231 \r
1232   delete vX;\r
1233   \r
1234   fListQAtof->Add(hSig);\r
1235 \r
1236   TH1F *hStartTimeMaskTOF = new TH1F("hStartTimeMask_TOF","StartTime mask",8,0,8);\r
1237   fListQAtof->Add(hStartTimeMaskTOF);\r
1238   TH1F *hStartTimeResTOF = new TH1F("hStartTimeRes_TOF","StartTime resolution [ps]",100,0,500);\r
1239   fListQAtof->Add(hStartTimeResTOF);\r
1240 \r
1241   TH1F *hnTracksAtTOF = new TH1F("hnTracksAt_TOF","Matched tracks at TOF",100,0,100);\r
1242   fListQAtof->Add(hnTracksAtTOF);\r
1243   TH1F *hT0MakerEff = new TH1F("hT0MakerEff","Events with T0-TOF vs nTracks",100,0,100);\r
1244   fListQAtof->Add(hT0MakerEff);\r
1245 \r
1246   // this in principle should stay on a T0 PID QA, but are just the data prepared for TOF use\r
1247   TH1F *hStartTimeAT0 = new TH1F("hStartTimeA_T0","StartTime from T0A [ps]",1000,-1000,1000);\r
1248   fListQAtof->Add(hStartTimeAT0);\r
1249   TH1F *hStartTimeCT0 = new TH1F("hStartTimeC_T0","StartTime from T0C [ps]",1000,-1000,1000);\r
1250   fListQAtof->Add(hStartTimeCT0);\r
1251   TH1F *hStartTimeACT0 = new TH1F("hStartTimeAC_T0","StartTime from T0AC [ps]",1000,-1000,1000);;\r
1252   fListQAtof->Add(hStartTimeACT0);\r
1253 }\r
1254 \r
1255 \r
1256 //______________________________________________________________________________\r
1257 void AliAnalysisTaskPIDqa::SetupT0qa()\r
1258 {\r
1259   //\r
1260   // Create the T0 qa objects\r
1261   //\r
1262   \r
1263   // these are similar to plots inside TOFqa, but these are for all events\r
1264   TH1F *hStartTimeAT0 = new TH1F("hStartTimeA_T0","StartTime from T0A [ps]",1000,-1000,1000);\r
1265   fListQAt0->Add(hStartTimeAT0);\r
1266   TH1F *hStartTimeCT0 = new TH1F("hStartTimeC_T0","StartTime from T0C [ps]",1000,-1000,1000);\r
1267   fListQAt0->Add(hStartTimeCT0);\r
1268   TH1F *hStartTimeACT0 = new TH1F("hStartTimeAC_T0","StartTime from T0AC [ps]",1000,-1000,1000);;\r
1269   fListQAt0->Add(hStartTimeACT0);\r
1270 \r
1271   TH1F *hnTracksAtT0 = new TH1F("hnTracksAt_T0","Tracks for events selected for T0",100,0,100);\r
1272   fListQAt0->Add(hnTracksAtT0);\r
1273   TH1F *hT0AEff = new TH1F("hT0AEff","Events with T0A vs nTracks",100,0,100);\r
1274   fListQAt0->Add(hT0AEff);\r
1275   TH1F *hT0CEff = new TH1F("hT0CEff","Events with T0C vs nTracks",100,0,100);\r
1276   fListQAt0->Add(hT0CEff);\r
1277   TH1F *hT0AndEff = new TH1F("hT0AndEff","Events with T0AC (AND) vs nTracks",100,0,100);\r
1278   fListQAt0->Add(hT0AndEff);\r
1279   TH1F *hT0OrEff = new TH1F("hT0OrEff","Events with T0AC (OR) vs nTracks",100,0,100);\r
1280   fListQAt0->Add(hT0OrEff);\r
1281 \r
1282 \r
1283 }\r
1284 \r
1285 //______________________________________________________________________________\r
1286 void AliAnalysisTaskPIDqa::SetupEMCALqa()\r
1287 {\r
1288   //\r
1289   // Create the EMCAL qa objects\r
1290   //\r
1291 \r
1292   TVectorD *vX=MakeLogBinning(200,.1,30);\r
1293   \r
1294   TH2F *hNsigmaPt = new TH2F(Form("hNsigmaPt_EMCAL_%s",AliPID::ParticleName(0)),\r
1295                              Form("EMCAL n#sigma %s vs. p_{T};p_{T} [GeV]; n#sigma",AliPID::ParticleName(0)),\r
1296                              vX->GetNrows()-1,vX->GetMatrixArray(),\r
1297                              200,-10,10);\r
1298   fListQAemcal->Add(hNsigmaPt);  \r
1299   \r
1300 \r
1301   TH2F *hSigPtEle = new TH2F("hSigPt_EMCAL_Ele",\r
1302                         "EMCAL signal (E/p) vs. p_{T} for electrons;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",\r
1303                         vX->GetNrows()-1,vX->GetMatrixArray(),\r
1304                         200,0,2);\r
1305   fListQAemcal->Add(hSigPtEle);\r
1306 \r
1307   TH2F *hSigPtPions = new TH2F("hSigPt_EMCAL_Pions",\r
1308                         "EMCAL signal (E/p) vs. p_{T} for pions;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",\r
1309                         vX->GetNrows()-1,vX->GetMatrixArray(),\r
1310                         200,0,2);\r
1311   fListQAemcal->Add(hSigPtPions);\r
1312 \r
1313   TH2F *hSigPtProtons = new TH2F("hSigPt_EMCAL_Protons",\r
1314                         "EMCAL signal (E/p) vs. p_{T} for protons;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",\r
1315                         vX->GetNrows()-1,vX->GetMatrixArray(),\r
1316                         200,0,2);\r
1317   fListQAemcal->Add(hSigPtProtons);\r
1318 \r
1319   TH2F *hSigPtAntiProtons = new TH2F("hSigPt_EMCAL_Antiprotons",\r
1320                         "EMCAL signal (E/p) vs. p_{T} for antiprotons;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",\r
1321                         vX->GetNrows()-1,vX->GetMatrixArray(),\r
1322                         200,0,2);\r
1323   fListQAemcal->Add(hSigPtAntiProtons);\r
1324 \r
1325   delete vX;  \r
1326 }\r
1327 \r
1328 //______________________________________________________________________________\r
1329 void AliAnalysisTaskPIDqa::SetupHMPIDqa()\r
1330 {\r
1331   //\r
1332   // Create the HMPID qa objects\r
1333   //\r
1334   \r
1335   TH2F *hCkovAnglevsMom   = new TH2F("hCkovAnglevsMom",  "Cherenkov angle vs momnetum",500,0,5.,500,0,1);\r
1336   fListQAhmpid->Add(hCkovAnglevsMom);\r
1337   \r
1338 }\r
1339 \r
1340 //______________________________________________________________________________\r
1341 void AliAnalysisTaskPIDqa::SetupTOFHMPIDqa()\r
1342 {\r
1343   //\r
1344   // Create the HMPID qa objects\r
1345   //\r
1346   \r
1347   TH2F *hCkovAnglevsMomPion   = new TH2F("hCkovAnglevsMom_pion",  "Cherenkov angle vs momnetum for pions",500,0,5.,500,0,1);\r
1348   fListQAtofhmpid->Add(hCkovAnglevsMomPion);\r
1349   \r
1350   TH2F *hCkovAnglevsMomKaon   = new TH2F("hCkovAnglevsMom_kaon",  "Cherenkov angle vs momnetum for kaons",500,0,5.,500,0,1);\r
1351   fListQAtofhmpid->Add(hCkovAnglevsMomKaon);\r
1352   \r
1353   TH2F *hCkovAnglevsMomProton = new TH2F("hCkovAnglevsMom_proton","Cherenkov angle vs momnetum for protons",500,0,5.,500,0,1);\r
1354   fListQAtofhmpid->Add(hCkovAnglevsMomProton);\r
1355   \r
1356   \r
1357 }  \r
1358 \r
1359 //______________________________________________________________________________\r
1360 void AliAnalysisTaskPIDqa::SetupTPCTOFqa()\r
1361 {\r
1362   //\r
1363   // Create the qa objects for TPC + TOF combination\r
1364   //\r
1365   \r
1366   TVectorD *vX=MakeLogBinning(200,.1,30);\r
1367 \r
1368   //TPC signals after TOF cut\r
1369   for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
1370     TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_TOF_%s",AliPID::ParticleName(ispecie)),\r
1371                               Form("TPC n#sigma %s vs. p (after TOF 3#sigma cut);p_{TPC} [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
1372                               vX->GetNrows()-1,vX->GetMatrixArray(),\r
1373                               200,-10,10);\r
1374     fListQAtpctof->Add(hNsigmaP);\r
1375   }\r
1376 \r
1377   //TOF signals after TPC cut\r
1378   for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
1379     TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TOF_TPC_%s",AliPID::ParticleName(ispecie)),\r
1380                               Form("TOF n#sigma %s vs. p (after TPC n#sigma cut);p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
1381                               vX->GetNrows()-1,vX->GetMatrixArray(),\r
1382                               200,-10,10);\r
1383     fListQAtpctof->Add(hNsigmaP);\r
1384   }\r
1385 \r
1386   //EMCAL signal after TOF and TPC cut\r
1387   for (Int_t ispecie=0; ispecie<AliPID::kSPECIES; ++ispecie){\r
1388     TH2F *heopPt = new TH2F(Form("heopPt_TOF_TPC_%s",AliPID::ParticleName(ispecie)),\r
1389                             Form("EMCAL signal (E/p) %s vs. p_{T};p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",AliPID::ParticleName(ispecie)),\r
1390                             vX->GetNrows()-1,vX->GetMatrixArray(),\r
1391                             200,0,2);\r
1392     fListQAtpctof->Add(heopPt);\r
1393   }\r
1394 \r
1395   delete vX;\r
1396 }\r
1397 //______________________________________________________________________________\r
1398 void AliAnalysisTaskPIDqa::SetupV0qa()\r
1399 {\r
1400   //\r
1401   // Create the qa objects for V0 Kine cuts\r
1402   //\r
1403   \r
1404   TH2F *hArmenteros  = new TH2F("hArmenteros",  "Armenteros plot",200,-1.,1.,200,0.,0.4);\r
1405   fListQAV0->Add(hArmenteros);\r
1406  \r
1407 }\r
1408 \r
1409 //_____________________________________________________________________________\r
1410 void AliAnalysisTaskPIDqa::SetupQAinfo(){\r
1411   //\r
1412   // Setup the info of QA objects\r
1413   //\r
1414 \r
1415   TObjArray *arr=new TObjArray;\r
1416   arr->SetName("TPC_info");\r
1417   fListQAinfo->Add(arr);\r
1418 }\r
1419 \r
1420 //______________________________________________________________________________\r
1421 TVectorD* AliAnalysisTaskPIDqa::MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax)\r
1422 {\r
1423   //\r
1424   // Make logarithmic binning\r
1425   // the user has to delete the array afterwards!!!\r
1426   //\r
1427   \r
1428   //check limits\r
1429   if (xmin<1e-20 || xmax<1e-20){\r
1430     AliError("For Log binning xmin and xmax must be > 1e-20. Using linear binning instead!");\r
1431     return MakeLinBinning(nbinsX, xmin, xmax);\r
1432   }\r
1433   if (xmax<xmin){\r
1434     Double_t tmp=xmin;\r
1435     xmin=xmax;\r
1436     xmax=tmp;\r
1437   }\r
1438   TVectorD *binLim=new TVectorD(nbinsX+1);\r
1439   Double_t first=xmin;\r
1440   Double_t last=xmax;\r
1441   Double_t expMax=TMath::Log(last/first);\r
1442   for (Int_t i=0; i<nbinsX+1; ++i){\r
1443     (*binLim)[i]=first*TMath::Exp(expMax/nbinsX*(Double_t)i);\r
1444   }\r
1445   return binLim;\r
1446 }\r
1447 \r
1448 //______________________________________________________________________________\r
1449 TVectorD* AliAnalysisTaskPIDqa::MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax)\r
1450 {\r
1451   //\r
1452   // Make linear binning\r
1453   // the user has to delete the array afterwards!!!\r
1454   //\r
1455   if (xmax<xmin){\r
1456     Double_t tmp=xmin;\r
1457     xmin=xmax;\r
1458     xmax=tmp;\r
1459   }\r
1460   TVectorD *binLim=new TVectorD(nbinsX+1);\r
1461   Double_t first=xmin;\r
1462   Double_t last=xmax;\r
1463   Double_t binWidth=(last-first)/nbinsX;\r
1464   for (Int_t i=0; i<nbinsX+1; ++i){\r
1465     (*binLim)[i]=first+binWidth*(Double_t)i;\r
1466   }\r
1467   return binLim;\r
1468 }\r
1469 \r
1470 //_____________________________________________________________________________\r
1471 TVectorD* AliAnalysisTaskPIDqa::MakeArbitraryBinning(const char* bins)\r
1472 {\r
1473   //\r
1474   // Make arbitrary binning, bins separated by a ','\r
1475   //\r
1476   TString limits(bins);\r
1477   if (limits.IsNull()){\r
1478     AliError("Bin Limit string is empty, cannot add the variable");\r
1479     return 0x0;\r
1480   }\r
1481   \r
1482   TObjArray *arr=limits.Tokenize(",");\r
1483   Int_t nLimits=arr->GetEntries();\r
1484   if (nLimits<2){\r
1485     AliError("Need at leas 2 bin limits, cannot add the variable");\r
1486     delete arr;\r
1487     return 0x0;\r
1488   }\r
1489   \r
1490   TVectorD *binLimits=new TVectorD(nLimits);\r
1491   for (Int_t iLim=0; iLim<nLimits; ++iLim){\r
1492     (*binLimits)[iLim]=(static_cast<TObjString*>(arr->At(iLim)))->GetString().Atof();\r
1493   }\r
1494   \r
1495   delete arr;\r
1496   return binLimits;\r
1497 }\r
1498 \r