]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGPP/TOF/AliAnalysisTaskTOFqaID.cxx
Merge branch 'TPCdev' of https://git.cern.ch/reps/AliRoot into TPCdev
[u/mrichter/AliRoot.git] / PWGPP / TOF / AliAnalysisTaskTOFqaID.cxx
1 /*  created by fbellini@cern.ch on 29/04/2013 */
2 /*  last modified by fbellini   on 19/08/2013 */
3
4
5 #ifndef ALIANALYSISTASKTOFQAID_CXX
6 #define ALIANALYSISTASKTOFQAID_CXX
7
8 #include "TChain.h"
9 #include "TTree.h"
10 #include "TH1F.h"
11 #include "TH2F.h"
12 #include "TProfile.h"
13 #include "TCanvas.h"
14 #include "AliAnalysisTaskSE.h"
15 #include "AliAnalysisManager.h"
16 #include "AliVEvent.h"
17 #include "AliVTrack.h"
18 #include "AliESDEvent.h"
19 #include "AliMCEvent.h"
20 #include "AliMCParticle.h"
21 #include "AliESDInputHandler.h"
22 #include "AliMCEventHandler.h"
23 #include "AliESDpid.h"
24 #include "AliTOFPIDParams.h"
25 #include "AliCDBManager.h"
26 #include "AliTOFcalib.h"
27 #include "AliTOFT0maker.h"
28 #include "AliTOFT0v1.h"
29 #include "AliAnalysisTaskTOFqaID.h"
30 #include "AliAnalysisFilter.h"
31 #include "AliESDtrackCuts.h"
32 #include "AliLog.h"
33 #include "AliTOFRawStream.h"
34 #include "AliTOFGeometry.h"
35
36 ClassImp(AliAnalysisTaskTOFqaID)
37
38 //________________________________________________________________________
39 AliAnalysisTaskTOFqaID::AliAnalysisTaskTOFqaID() :
40   fRunNumber(0), 
41   fESD(0x0), 
42   fMCevent(0x0),
43   fTrackFilter(0x0), 
44   fVertex(0x0),
45   fESDpid(new AliESDpid()),
46   fTOFHeader(0x0),
47   fEnableAdvancedCheck(kFALSE),
48   fEnableChargeSplit(kFALSE),
49   fExpTimeBinWidth(24.4),
50   fExpTimeRangeMin(-25010.),
51   fExpTimeRangeMax(25010.),
52   fExpTimeSmallRangeMin(-5002.),
53   fExpTimeSmallRangeMax(5002.),
54   fnExpTimeBins(1),
55   fnExpTimeSmallBins(1),  
56   fMyTimeZeroTOF(1e20),
57   fMyTimeZeroTOFsigma(1e20),
58   fMyTimeZeroTOFtracks(-1),
59   fIsMC(kFALSE),
60   fSelectedPdg(0),
61   fP(1e10),
62   fPt(1e10),
63   fEta(1e10),
64   fPhi(1e10),
65   fTPCOuterPhi(1e10),
66   fL(1e10),
67   fMatchingMomCut(0.0),
68   fMatchingEtaCut(1e10),
69   fTof(1e10),
70   fHlist(0x0),
71   fHlistTimeZero(0x0),
72   fHlistPID(0x0),
73   fHlistTRD(0x0),
74   fHlistTrigger(0x0)
75 {
76   // Default constructor
77    
78    for (Int_t j=0;j<3;j++ ) {
79      if (j<3) {
80        fT0[j]=0.0;
81        fNTOFtracks[j]=0;
82      }
83      fSigmaSpecie[j]=0.0;
84      fTrkExpTimes[j]=0.0;
85      fThExpTimes[j]=0.0;
86    }
87 }
88 //________________________________________________________________________
89 AliAnalysisTaskTOFqaID::AliAnalysisTaskTOFqaID(const char *name) : 
90   AliAnalysisTaskSE(name), 
91   fRunNumber(0), 
92   fESD(0x0), 
93   fMCevent(0x0),
94   fTrackFilter(0x0),
95   fVertex(0x0),
96   fESDpid(new AliESDpid()),
97   fTOFHeader(0x0),
98   fEnableAdvancedCheck(kFALSE),
99   fEnableChargeSplit(kFALSE),
100   fExpTimeBinWidth(24.4),
101   fExpTimeRangeMin(-25010.),
102   fExpTimeRangeMax(25010.),
103   fExpTimeSmallRangeMin(-5002.),
104   fExpTimeSmallRangeMax(5002.),
105   fnExpTimeBins(1),
106   fnExpTimeSmallBins(1),
107   fMyTimeZeroTOF(1e20),
108   fMyTimeZeroTOFsigma(1e20),
109   fMyTimeZeroTOFtracks(-1),
110   fIsMC(kFALSE),
111   fSelectedPdg(0),
112   fP(1e10),
113   fPt(1e10),
114   fEta(1e10),
115   fPhi(1e10),
116   fTPCOuterPhi(1e10),
117   fL(1e10),
118   fMatchingMomCut(1.0),
119   fMatchingEtaCut(0.8),
120   fTof(1e10),
121   fHlist(0x0),
122   fHlistTimeZero(0x0),
123   fHlistPID(0x0),
124   fHlistTRD(0x0),
125   fHlistTrigger(0x0)
126  {
127   // Constructor
128   // Define input and output slots here
129    Info("AliAnalysisTaskTOFqaID","Calling Constructor");
130    
131    for (Int_t j=0;j<5;j++ ) {
132      if (j<3){ 
133        fT0[j]=0.0;
134        fNTOFtracks[j]=0;
135      }
136      fSigmaSpecie[j]=0.0;
137      fTrkExpTimes[j]=0.0;
138      fThExpTimes[j]=0.0;
139    }
140    // Input slot #0 works with a TChain
141    DefineInput(0, TChain::Class());
142    
143    // Output slot #0 writes into a TH1 container
144    // Output slot #1 writes into a user defined  container
145    DefineOutput(1, TList::Class());
146    DefineOutput(2, TList::Class());
147    DefineOutput(3, TList::Class());
148    DefineOutput(4, TList::Class());
149    DefineOutput(5, TList::Class());
150    
151  }
152
153 //________________________________________________________________________
154 AliAnalysisTaskTOFqaID::AliAnalysisTaskTOFqaID(const AliAnalysisTaskTOFqaID& copy) 
155 : AliAnalysisTaskSE(), 
156   fRunNumber(copy.fRunNumber), 
157   fESD(copy.fESD), 
158   fMCevent(copy.fMCevent),
159   fTrackFilter(copy.fTrackFilter), 
160   fVertex(copy.fVertex),
161   fESDpid(copy.fESDpid),
162   fTOFHeader(copy.fTOFHeader),
163   fEnableAdvancedCheck(copy.fEnableAdvancedCheck),
164   fEnableChargeSplit(copy.fEnableChargeSplit),
165   fExpTimeBinWidth(copy.fExpTimeBinWidth),
166   fExpTimeRangeMin(copy.fExpTimeRangeMin),
167   fExpTimeRangeMax(copy.fExpTimeRangeMax),
168   fExpTimeSmallRangeMin(copy.fExpTimeSmallRangeMin),
169   fExpTimeSmallRangeMax(copy.fExpTimeSmallRangeMax),
170   fnExpTimeBins(copy.fnExpTimeBins),
171   fnExpTimeSmallBins(copy.fnExpTimeSmallBins),
172   fMyTimeZeroTOF(copy.fMyTimeZeroTOF),
173   fMyTimeZeroTOFsigma(copy.fMyTimeZeroTOFsigma),
174   fMyTimeZeroTOFtracks(copy.fMyTimeZeroTOFtracks),
175   fIsMC(copy.fIsMC),
176   fSelectedPdg(copy.fSelectedPdg),
177   fP(copy.fP),
178   fPt(copy.fPt),
179   fEta(copy.fEta),
180   fPhi(copy.fPhi),
181   fTPCOuterPhi(copy.fTPCOuterPhi),
182   fL(copy.fL),
183   fMatchingMomCut(copy.fMatchingMomCut),
184   fMatchingEtaCut(copy.fMatchingEtaCut),
185   fTof(copy.fTof),
186   fHlist(copy.fHlist),
187   fHlistTimeZero(copy.fHlistTimeZero),
188   fHlistPID(copy.fHlistPID),
189   fHlistTRD(copy.fHlistTRD),
190   fHlistTrigger(copy.fHlistTrigger)
191 {
192   // Copy constructor
193    for (Int_t j=0;j<5;j++ ) {
194      if (j<3) { 
195        fT0[j]=copy.fT0[j];
196        fNTOFtracks[j]=copy.fNTOFtracks[j];
197      }
198      fSigmaSpecie[j]=copy.fSigmaSpecie[j];
199      fTrkExpTimes[j]=copy.fTrkExpTimes[j];
200      fThExpTimes[j]=copy.fThExpTimes[j];
201    }
202   
203
204 }
205
206 //___________________________________________________________________________
207 AliAnalysisTaskTOFqaID& AliAnalysisTaskTOFqaID::operator=(const AliAnalysisTaskTOFqaID& copy) 
208 {
209   //
210   // Assignment operator
211   //
212   if (this!=&copy) {
213     AliAnalysisTaskSE::operator=(copy) ;
214     fRunNumber=copy.fRunNumber; 
215     fESD=copy.fESD;
216     fMCevent=copy.fMCevent;
217     fTrackFilter=copy.fTrackFilter;
218     fVertex=copy.fVertex;
219     fESDpid=copy.fESDpid;
220     fTOFHeader=copy.fTOFHeader;
221     fEnableAdvancedCheck=copy.fEnableAdvancedCheck;
222     fEnableChargeSplit=copy.fEnableChargeSplit;
223     fExpTimeBinWidth=copy.fExpTimeBinWidth;
224     fExpTimeRangeMin=copy.fExpTimeRangeMin;
225     fExpTimeRangeMax=copy.fExpTimeRangeMax;
226     fExpTimeSmallRangeMin=copy.fExpTimeSmallRangeMin;
227     fExpTimeSmallRangeMax=copy.fExpTimeSmallRangeMax;
228     fnExpTimeBins=copy.fnExpTimeBins;
229     fnExpTimeSmallBins=copy.fnExpTimeSmallBins;
230     fMyTimeZeroTOF=copy.fMyTimeZeroTOF;
231     fMyTimeZeroTOFsigma=copy.fMyTimeZeroTOFsigma;
232     fMyTimeZeroTOFtracks=copy.fMyTimeZeroTOFtracks;
233     for (Int_t j=0;j<5;j++ ) {
234       if (j<3) {
235         fT0[j]=copy.fT0[j];
236         fNTOFtracks[j]=copy.fNTOFtracks[j];
237       }
238       fSigmaSpecie[j]=copy.fSigmaSpecie[j];
239       fTrkExpTimes[j]=copy.fTrkExpTimes[j];
240       fThExpTimes[j]=copy.fThExpTimes[j];
241     }
242     fIsMC=copy.fIsMC;
243     fSelectedPdg=copy.fSelectedPdg;
244     fP=copy.fP;
245     fPt=copy.fPt;
246     fEta=copy.fEta;
247     fPhi=copy.fPhi;
248     fTPCOuterPhi=copy.fTPCOuterPhi;
249     fL=copy.fL;
250     fMatchingMomCut=copy.fMatchingMomCut;
251     fMatchingEtaCut=copy.fMatchingEtaCut;
252     fTof=copy.fTof;
253     fHlist=copy.fHlist;
254     fHlistTimeZero=copy.fHlistTimeZero;
255     fHlistPID=copy.fHlistPID;
256     fHlistTRD=copy.fHlistTRD;
257     fHlistTrigger=copy.fHlistTrigger;
258   }
259   return *this;
260 }
261
262 //___________________________________________________________________________
263 AliAnalysisTaskTOFqaID::~AliAnalysisTaskTOFqaID() {
264   //
265   //destructor
266   //
267
268   Info("~AliAnalysisTaskTOFqaID","Calling Destructor");
269   if (fESDpid) delete fESDpid;
270   if (fTOFHeader) delete fTOFHeader;
271   if (fVertex) delete fVertex;
272   if (fTrackFilter) delete fTrackFilter;
273   if (AliAnalysisManager::GetAnalysisManager()->IsProofMode()) return;  
274
275   if (fHlist) {
276     delete fHlist;
277     fHlist = 0;
278   }
279   if (fHlistTimeZero) {
280     delete fHlistTimeZero;
281     fHlistTimeZero = 0;
282   }
283   if (fHlistPID){
284     delete fHlistPID;
285     fHlistPID = 0;
286   }
287   if (fHlistTRD){
288     delete fHlistTRD;
289     fHlistTRD = 0;
290   }
291   if (fHlistTrigger){
292     delete fHlistTrigger;
293     fHlistTrigger = 0;
294   }
295 }
296
297 //________________________________________________________________________
298 void AliAnalysisTaskTOFqaID::UserCreateOutputObjects()
299 {
300   //
301   //Define output objects and histograms
302   //
303
304   //retrieve PID response object 
305   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
306   if (!man)  AliFatal("Analysis manager needed");
307   AliInputEventHandler *inputHandler=dynamic_cast<AliInputEventHandler*>(man->GetInputEventHandler());
308   if (!inputHandler) AliFatal("Input handler needed");
309   //pid response object
310   fESDpid=(AliESDpid*)inputHandler->GetPIDResponse();
311   if (!fESDpid) AliError("PIDResponse object was not created");
312   //fESDpid->SetOADBPath("$ALICE_ROOT/OADB");
313
314   Info("CreateOutputObjects","CreateOutputObjects (TList) of task %s", GetName());
315   OpenFile(1);
316
317   if (!fHlist) fHlist = new TList();    
318   fHlist->SetOwner(kTRUE);
319   fHlist->SetName("base");
320
321   if (!fHlistTimeZero) fHlistTimeZero = new TList();    
322   fHlistTimeZero->SetOwner(kTRUE);
323   fHlistTimeZero->SetName("startTime");
324
325   if (!fHlistPID) fHlistPID = new TList();      
326   fHlistPID->SetOwner(kTRUE);
327   fHlistPID->SetName("pid");
328
329   if (!fHlistTRD) fHlistTRD = new TList();      
330   fHlistTRD->SetOwner(kTRUE);  
331   fHlistTRD->SetName("TRD");
332
333   if (!fHlistTrigger) fHlistTrigger = new TList();      
334   fHlistTrigger->SetOwner(kTRUE);  
335   fHlistTrigger->SetName("trigger");
336
337   if (fExpTimeRangeMax<fExpTimeRangeMin) {
338     SetExpTimeHistoRange(-25010.,25010.);
339   }
340   fnExpTimeBins = TMath::Nint((fExpTimeRangeMax - fExpTimeRangeMin)/fExpTimeBinWidth);//ps
341   fExpTimeRangeMax=fExpTimeRangeMin+fnExpTimeBins*fExpTimeBinWidth;//ps
342   
343   if (fExpTimeSmallRangeMax<fExpTimeSmallRangeMin) {
344     SetExpTimeHistoSmallRange(-5002.,5002.);
345   }
346   fnExpTimeSmallBins = TMath::Nint((fExpTimeSmallRangeMax - fExpTimeSmallRangeMin)/fExpTimeBinWidth);//ps
347   fExpTimeSmallRangeMax=fExpTimeSmallRangeMin+fnExpTimeSmallBins*fExpTimeBinWidth;//ps
348   
349   //add plots for start time QA
350   AddStartTimeHisto(fHlistTimeZero,"");
351   
352   //add plots for base TOF quantities
353   if (fEnableChargeSplit) {
354     AddTofBaseHisto(fHlist,  1, "");
355     AddTofBaseHisto(fHlist, -1, "");
356   } else {
357     AddTofBaseHisto(fHlist,  0, "");
358   }
359   //add plots for matching efficiency
360    if (fEnableChargeSplit) {
361      AddMatchingEffHisto(fHlist,  1, "");
362      AddMatchingEffHisto(fHlist, -1, "");
363    } else {
364      AddMatchingEffHisto(fHlist,  0, "");
365    }
366   //add plots for PID checks
367    if (fEnableChargeSplit) {
368      AddPidHisto(fHlistPID,  1, ""); 
369      AddPidHisto(fHlistPID, -1, ""); 
370    } else {
371      AddPidHisto(fHlistPID,  0, ""); 
372    }
373   //add trd plots
374   if (fEnableAdvancedCheck) {
375     AddTrdHisto();
376   }
377   //Add trigger plots
378   AddTofTrgHisto("");
379   
380   PostData(1, fHlist);
381   PostData(2, fHlistTimeZero);
382   PostData(3, fHlistPID);
383   PostData(4, fHlistTRD);
384   PostData(5, fHlistTrigger);
385 }
386 //________________________________________________________________________
387 void AliAnalysisTaskTOFqaID::UserExec(Option_t *) 
388
389   /* Main - executed for each event.
390     It extracts event information and track information after selecting 
391     primary tracks via standard cuts. */
392   /*
393   AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
394   if (!esdH) {
395     AliError("ERROR: Could not get ESDInputHandler");
396     return;
397   } else {
398     fESD = (AliESDEvent*) esdH->GetEvent();
399   } 
400   
401   */
402   fESD=(AliESDEvent*)InputEvent();
403   if (!fESD) {
404     AliError("fESD event not available");
405     return;
406   }
407   
408   if (!fESDpid) {
409     AliError("PID object fESDpid not available");
410     return;
411   }
412   
413   //retrieve default start time type from PIDresponse
414   AliPIDResponse::EStartTimeType_t startTimeMethodDefault = AliPIDResponse::kBest_T0;  
415   if (fESDpid->GetTOFPIDParams()) {  // during reconstruction OADB not yet available
416     startTimeMethodDefault = ((AliTOFPIDParams *)fESDpid->GetTOFPIDParams())->GetStartTimeMethod();
417   }
418   
419   //access MC event handler for MC truth information
420   if (fIsMC) {
421     AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
422     if (!mcH) {
423       AliError("Cannot get MCeventHandler");
424       return;
425     } else {
426       fMCevent = (AliMCEvent *) mcH->MCEvent();
427       if (!fMCevent) {
428         AliError("Trying to retrieve an invalid MC event.");
429         return;
430       }
431     }
432   }
433   
434   // get run number
435   Int_t runNb = fESD->GetRunNumber();
436   if (runNb>0) fRunNumber = runNb;  
437
438   //reset matched track counters
439   for (Int_t j=0;j<3;j++){fNTOFtracks[j]=0;}  
440
441   //Get vertex info and apply vertex cut
442   if (!IsEventSelected(fESD)) return;
443   
444   //set response tof_t0 for all other checks
445   fESDpid->SetTOFResponse(fESD,AliESDpid::kTOF_T0);//(fill_t0, tof_t0, t0_t0, best_t0)
446   
447   AliDebug(3, Form("Momentum cut for eta and phi distributions set: Pt>%3.2f", fMatchingMomCut));
448
449   //check existence of track filter
450   if (!fTrackFilter){
451     AliInfo("No track filter found, skipping the track loop");
452     return;
453   }
454   
455   // loop over ESD tracks
456   for (Int_t iTracks = 0; iTracks < fESD->GetNumberOfTracks(); iTracks++) {
457     AliESDtrack* track = fESD->GetTrack(iTracks);
458     if (!track) {
459       AliInfo(Form("Cannot receive track %d", iTracks));
460       continue;
461     }
462     
463     //primary tracks selection: kTPCrefit and std cuts
464     if (!fTrackFilter->IsSelected(track)) continue;
465     
466     //select specie if MC
467     if ( fIsMC && 
468          (!SelectMCspecies(fMCevent, track))) {
469       AliDebug(4, Form("MC tracks selection: Track=%i  label=%i  Not Accepted", iTracks, track->GetLabel()));
470       continue;
471     }
472     
473     //apply cut for eta acceptance
474     fEta=track->Eta();
475     if (TMath::Abs(fEta)>fMatchingEtaCut) continue; 
476     
477     //get other track variables
478     fP = track->P();
479     fPt = track->Pt();
480     fPhi = track->Phi()*TMath::RadToDeg();
481     fTPCOuterPhi = GetPhiAtTPCouterRadius(track);
482     fL = track->GetIntegratedLength();
483     track->GetIntegratedTimes(fTrkExpTimes);
484     
485     Int_t charge = 0;
486     if (fEnableChargeSplit) charge = track->Charge();
487     
488     //Fill histograms for primary particles
489     FillPrimaryTrkHisto(charge,"");
490     
491     if (IsTPCTOFMatched(track)) {     
492       fTof=track->GetTOFsignal()*1E-3;//in ps
493       //increment track counters
494       fNTOFtracks[0]++;
495       if (charge>0) fNTOFtracks[1]++;
496       if (charge<0) fNTOFtracks[2]++;
497       //fill histos
498       FillTofBaseHisto(track, charge,"");
499       FillMatchedTrkHisto(charge,"");
500       FillPidHisto(track, charge, "");
501     }    
502     if (fEnableAdvancedCheck) FillTrdHisto(track, charge);
503   }//end loop on tracks
504   
505   //fill time zero histos  
506   FillStartTimeHisto("");  
507   if (fEnableChargeSplit) {
508     ((TH1F*)fHlist->FindObject("hTOFmulti_pos"))->Fill(fNTOFtracks[1]);
509     ((TH1F*)fHlist->FindObject("hTOFmulti_neg"))->Fill(fNTOFtracks[2]);
510   } else {
511     ((TH1F*)fHlist->FindObject("hTOFmulti_all"))->Fill(fNTOFtracks[0]);
512   }
513   //fill TOF trg histos from infos in TOF header
514   fTOFHeader=(AliTOFHeader*)fESD->GetTOFHeader();
515   if (!fTOFHeader) {
516     AliWarning("Cannot get TOF header: no TOF trigger info available");
517   } else {
518     FillTofTrgHisto("");
519   }
520   
521   //restore value set by AliPIDResponseTask for subsequent wagons
522   fESDpid->SetTOFResponse(fESD,startTimeMethodDefault);
523   
524   PostData(1, fHlist);
525   PostData(2, fHlistTimeZero);
526   PostData(3, fHlistPID);
527   PostData(4, fHlistTRD);
528   PostData(5, fHlistTrigger);
529
530 }      
531
532 //________________________________________________________________________
533 void AliAnalysisTaskTOFqaID::Terminate(Option_t *) 
534 {
535   //check on output validity
536   fHlist = dynamic_cast<TList*> (GetOutputData(1));
537   if (!fHlist) {
538     AliError("Base histograms list not available");
539     return;   
540   } 
541   
542   // TH1F*hDummy = ((TH1F*)fHlist->FindObject("hTOFmatchedESDPt"));
543   // TH1F*hMatchingEff = (TH1F*) hDummy->Clone("hMatchingEff");
544   // hMatchingEff->SetTitle("Matching efficiency");
545   // hMatchingEff->Divide((TH1F*) fHlist->FindObject("hESDprimaryTrackPt"));
546   // TCanvas *c1 = new TCanvas("AliAnalysisTaskTOFqaID","Matching vs Pt",10,10,510,510);
547   // c1->cd(1)->SetLogy();
548   // hMatchingEff->DrawCopy("E");
549   // fHlist->AddLast(hMatchingEff);
550   ComputeMatchingEfficiency(fHlist, "pt");
551   ComputeMatchingEfficiency(fHlist, "eta");
552   ComputeMatchingEfficiency(fHlist, "phi");
553
554   PostData(1, fHlist);
555 }
556
557 //---------------------------------------------------------------
558 Int_t AliAnalysisTaskTOFqaID::GetStripIndex(const Int_t * in)
559 {
560   /* return tof strip index between 0 and 91 */
561   
562   Int_t nStripA = AliTOFGeometry::NStripA();
563   Int_t nStripB = AliTOFGeometry::NStripB();
564   Int_t nStripC = AliTOFGeometry::NStripC();
565
566   Int_t iplate = in[1];
567   Int_t istrip = in[2];
568   
569   Int_t stripOffset = 0;
570   switch (iplate) {
571   case 0:
572     stripOffset = 0;
573       break;
574   case 1:
575     stripOffset = nStripC;
576     break;
577   case 2:
578     stripOffset = nStripC+nStripB;
579     break;
580   case 3:
581     stripOffset = nStripC+nStripB+nStripA;
582     break;
583   case 4:
584     stripOffset = nStripC+nStripB+nStripA+nStripB;
585     break;
586   default:
587     stripOffset=-1;
588     break;
589   };
590   
591   if (stripOffset<0 || stripOffset>92) return -1;
592   else 
593     return (stripOffset+istrip);
594 }
595
596 //-----------------------------------------------------------------
597 Double_t AliAnalysisTaskTOFqaID::GetPhiAtTPCouterRadius(AliESDtrack * track)
598 {
599   //get track phi at TPC outer radius
600   if (!track) return 1e10;
601   Double_t tpcoutcoord[3]={0.,0.,0.};
602   track->GetOuterXYZ(tpcoutcoord);
603   Double_t phiOuterTPC=TMath::ATan2(tpcoutcoord[1],tpcoutcoord[0])*TMath::RadToDeg();
604   if (phiOuterTPC<0) 
605     phiOuterTPC+= (2*TMath::Pi()*TMath::RadToDeg());
606   return phiOuterTPC;
607 }
608 //-----------------------------------------------------------------
609 Bool_t  AliAnalysisTaskTOFqaID::IsEventSelected(AliESDEvent * event)
610 {
611   //select event based on primary vertex
612   if (!event) {
613     AliError("Invalid ESD event");
614     return kFALSE;
615   }
616   fVertex = (AliESDVertex*) event->GetPrimaryVertexTracks(); 
617   if(fVertex->GetNContributors()<1) { 
618     // SPD vertex
619     fVertex = (AliESDVertex*) event->GetPrimaryVertexSPD(); 
620     if(fVertex->GetNContributors()<1) fVertex = 0x0;
621   }
622   if (!fVertex) return kFALSE; 
623   if (TMath::Abs(fVertex->GetZ())<10.0) return kTRUE;
624   else return kFALSE;
625 }
626
627 //-----------------------------------------------------------------
628 Bool_t  AliAnalysisTaskTOFqaID::IsTPCTOFMatched(AliESDtrack * track)
629 {
630   //defines TOF matching
631   if (!track){
632     AliWarning("Invalid track object");
633     return kFALSE;
634   }
635   
636   if ( (track->IsOn(AliESDtrack::kTOFout)) &&
637        (track->IsOn(AliESDtrack::kTIME)) &&
638        (track->IsOn(AliESDtrack::kTPCout))  )
639     return kTRUE;
640   else 
641     return kFALSE;
642 }
643 //-----------------------------------------------------------------
644 Bool_t  AliAnalysisTaskTOFqaID::IsInTRD(AliESDtrack * track)
645 {
646   //defines cut to select particles in/out TRD
647   if (!track){
648     AliWarning("Invalid track object");
649     return kFALSE;
650   }
651   
652   if ( track->IsOn(AliESDtrack::kTPCout) 
653        && track->IsOn(AliESDtrack::kTRDout) )
654     return kTRUE;
655   else 
656     return kFALSE; 
657 }
658 //-----------------------------------------------------------------
659 void AliAnalysisTaskTOFqaID::FillStartTimeMaskHisto(TString suffix)
660 {
661   /* set pid response to use best_T0 and for each
662      accepted track fills the histogram with the 
663      used start time 
664   */
665
666   //set response best_t0 
667   //fESDpid->SetTOFResponse(fESD,AliESDpid::kBest_T0);
668
669   for (Int_t iTracks = 0; iTracks < fESD->GetNumberOfTracks(); iTracks++) {
670     AliESDtrack* track = fESD->GetTrack(iTracks);
671     if (!track) {
672       AliInfo(Form("Cannot receive track %d", iTracks));
673       continue;
674     }    
675     //primary tracks selection: kTPCrefit and std cuts
676     if (fTrackFilter){
677       if(!fTrackFilter->IsSelected(track)) continue;
678     }
679     else{
680       AliInfo("No track filter found, skipping the track loop");
681       break;
682     }
683     if (TMath::Abs(track->Eta())>fMatchingEtaCut) continue; //cut for acceptance  
684     
685     Int_t StartTimeBit = fESDpid->GetTOFResponse().GetStartTimeMask(track->P());
686     ((TH2F*)fHlistTimeZero->FindObject(Form("hStartTimeMask%s",suffix.Data())))->Fill(track->P(),StartTimeBit);
687     
688     //matched tracks selection: kTOFout and kTIME
689     if ( (track->IsOn(AliESDtrack::kTOFout)) &&
690          (track->IsOn(AliESDtrack::kTIME)) &&
691          (track->IsOn(AliESDtrack::kTPCout))  ) {
692       ((TH2F*)fHlistTimeZero->FindObject(Form("hStartTimeMaskMatched%s",suffix.Data())))->Fill(track->P(),StartTimeBit);
693     }
694   }
695   return;
696 }
697
698 //----------------------------------------------------
699 Bool_t AliAnalysisTaskTOFqaID::ComputeTimeZeroByTOF1GeV()
700 {
701   /* compute T0-TOF for tracks within momentum range [0.95, 1.05] */
702   /* init T0-TOF */
703   AliTOFT0v1 *fTOFT0v1 = new AliTOFT0v1(fESDpid); // TOF-T0 v1
704   fTOFT0v1->Init(fESD);
705   fTOFT0v1->DefineT0("all", 0.95, 1.05);
706   fMyTimeZeroTOF = -1000. * fTOFT0v1->GetResult(0);
707   fMyTimeZeroTOFsigma = 1000. * fTOFT0v1->GetResult(1);
708   fMyTimeZeroTOFtracks = fTOFT0v1->GetResult(3);
709   Bool_t hasTimeZeroTOF = kFALSE;
710   /* check T0-TOF sigma */
711   if (fMyTimeZeroTOFsigma < 250.)
712     hasTimeZeroTOF = kTRUE;  
713   return hasTimeZeroTOF;
714 }
715
716 //------------------------------------------------------
717 TString AliAnalysisTaskTOFqaID::GetSpeciesName(Int_t absPdgCode)
718 {
719   //returns name of selected specie 
720   TString name;
721   switch (absPdgCode){
722   case 11:
723     name = "electron";
724     break;
725   case 13:
726     name = "muon";
727     break;
728   case 211:
729     name = "pion";
730     break;
731   case 321:
732     name = "kaon";
733       break;
734   case 2212:
735     name = "proton";
736     break;
737   default:
738     name = "noPID";
739     break;
740   }
741   return name.Data();
742 }
743
744 //-----------------------------------------------
745 Bool_t AliAnalysisTaskTOFqaID::SelectMCspecies(AliMCEvent * ev, AliESDtrack * track)
746 {
747   //
748   //Retrieves particle true ID from MC and selects the desired species
749   //
750   if ((!ev) || (!track)) {
751     AliError("SelectMCspecies - Invalid object set as argument");
752     return kFALSE;
753   }
754   
755   if (fSelectedPdg==0) return kTRUE;   //if fSelectedPdg==0, no species selection is applied
756
757   Long_t label = track->GetLabel();
758   if (label<0) return kFALSE;
759   
760   // get number of particles
761   Long_t nMC = ev->GetNumberOfTracks();
762   // if label too large --> failed
763   if (label>= nMC) {
764     AliWarning(Form("Stack overflow: track label = %li -- stack maximum = %li", label, nMC));
765     return kFALSE;
766   } 
767   // retrieve particle
768   AliMCParticle *mcPart = (AliMCParticle *)ev->GetTrack(label);
769   if (!mcPart) {// if particle = NULL --> failed
770     AliWarning(Form("Stack discontinuity: label %li refers to a NULL object", label));
771     return kFALSE;
772   }
773
774   Int_t pdgCode = mcPart->PdgCode();
775   if (!(TMath::Abs(pdgCode)==fSelectedPdg))
776     return kFALSE;
777   else  
778     return  kTRUE;
779 }
780
781 //----------------------------------------------------------------------------------
782 Bool_t  AliAnalysisTaskTOFqaID::ComputeMatchingEfficiency(TList* list, TString variable)
783 {
784   //computes matching efficiency from previously filled histos
785   // to be called in terminate function  
786   if (!list) return kFALSE;
787
788   TString matchedName, primaryName, xAxisTitle;
789   if (variable.Contains("pt")) {
790     matchedName = "hTOFmatchedESDPt";
791     primaryName = "hESDprimaryTrackPt";
792     xAxisTitle = "p_{T} (GeV/c)";
793   }
794   if (variable.Contains("eta")) {
795     matchedName = "hTOFmatchedESDeta";
796     primaryName = "hTOFprimaryESDeta";
797     xAxisTitle = "#eta";
798   }
799   if (variable.Contains("phi")) {
800     matchedName = "hTOFmatchedESDphi";
801     primaryName = "hTOFprimaryESDphi";
802     xAxisTitle = "#phi_vtx (deg)";
803   }
804   
805   TH1F*hDummy = ((TH1F*)list->FindObject(matchedName.Data()));
806   if (!hDummy) return 0;
807
808   TH1F*hMatchingEff = (TH1F*) hDummy->Clone("hMatchingEff");
809   hMatchingEff->SetNameTitle(Form("hMatchingEff_%s", variable.Data()),Form("Matching efficiency vs %s", variable.Data()));
810   hMatchingEff->Divide((TH1F*) list->FindObject(primaryName.Data()));
811   hMatchingEff->GetXaxis()->SetTitle(xAxisTitle.Data());
812   hMatchingEff->GetYaxis()->SetRangeUser(0.0,1.0);
813   hMatchingEff->GetYaxis()->SetTitle("#epsilon_{match}");
814   list->AddLast(hMatchingEff);
815   return 1;
816 }
817 //----------------------------------------------------------------------------------
818 void AliAnalysisTaskTOFqaID::HistogramMakeUp(TH1* hist, Color_t color, Int_t markerStyle, TString drawOpt, TString newName, TString newTitle, TString xTitle, TString yTitle)
819 {
820   //set histogram style and axes style at once
821   if (!hist) return;  
822   if (!newName.IsNull()) hist->SetName(newName.Data());
823   if (!newTitle.IsNull()) hist->SetTitle(newTitle.Data());
824   if (!xTitle.IsNull()) hist->GetXaxis()->SetTitle(xTitle.Data());
825   if (!yTitle.IsNull()) hist->GetYaxis()->SetTitle(yTitle.Data());
826   hist->SetLineColor(color);
827   hist->SetMarkerColor(color);
828   hist->SetMarkerStyle(markerStyle);
829   hist->SetMarkerSize(0.7);
830   hist->SetDrawOption(drawOpt.Data());
831   //hist->Sumw2();
832   return;
833 }
834
835 //----------------------------------------------------------------------------------
836 void AliAnalysisTaskTOFqaID::AddTofBaseHisto(TList *list, Int_t charge, TString suffix)
837 {
838   //Creates histograms for monitoring TOF signal, time alignement and matching-related quantities
839   if (!list){
840     AliError("Invalid list passed as argument.");
841     return;
842   }
843  
844   TString cLabel; 
845   if (charge == 0) cLabel.Form("all");
846   else 
847     if (charge<0) cLabel.Form("neg"); 
848     else 
849       if (charge>0) cLabel.Form("pos"); 
850   
851   
852   TH1I* hTOFmulti = new TH1I(Form("hTOFmulti%s_%s",suffix.Data(), cLabel.Data()), Form("%s matched trk per event (|#eta|#leq%3.2f, p_{T}#geq0.3 GeV/c)", cLabel.Data(), fMatchingEtaCut), 100, 0, 100);  
853   HistogramMakeUp(hTOFmulti, ((charge>0)? kRed : kBlue+2), 1, "E1", "","", "N","events");
854   list->AddLast(hTOFmulti);
855   
856   TH1F* hTOFtime = new TH1F(Form("hTime%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk TOF signal", cLabel.Data()), 250, 0., 610. ) ; 
857   HistogramMakeUp(hTOFtime,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "t (ns)","tracks");
858   list->AddLast(hTOFtime);
859   
860   TH1F* hTOFrawTime = new TH1F(Form("hRawTime%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk TOF raw signal", cLabel.Data()), 250, 0., 610. ) ; 
861   HistogramMakeUp(hTOFrawTime,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "t_{raw} (ns)","tracks");
862   list->AddLast(hTOFrawTime);
863
864   TH1F* hTOFtot = new TH1F(Form("hTot%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk ToT", cLabel.Data()), 50, 0., 50. ) ; 
865   HistogramMakeUp(hTOFtot,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "ToT (ns)","tracks");
866   list->AddLast(hTOFtot);
867     
868   TH1F* hMatchedL  = new TH1F(Form("hMatchedL%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk lenght", cLabel.Data()), 900, -100., 800) ; 
869   HistogramMakeUp(hMatchedL,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "L (cm)","tracks");
870   list->AddLast(hMatchedL);
871   
872   const Int_t nBinsPt = 300;
873   Double_t xBins[nBinsPt+1];
874   for (Int_t j=0;j<nBinsPt+1; j++) {  
875     if (j<200) xBins[j] = j*0.025;
876     else xBins[j] = 5.0 + (j-200)*0.050;  
877   }
878
879   TH2F* hMatchedDxVsPt = new TH2F(Form("hMatchedDxVsPt%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk dx vs.p_{T}", cLabel.Data()), nBinsPt, xBins, 200, -10., 10.); 
880   HistogramMakeUp(hMatchedDxVsPt,((charge>0)? kRed+2 : kBlue+2), 1, "colz", "","", "p_{T} (GeV/c)","dx (cm)");
881   list->AddLast(hMatchedDxVsPt); 
882
883   TH2F* hMatchedDzVsStrip = new TH2F(Form("hMatchedDzVsStrip%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk dz vs. strip (#eta)", cLabel.Data()), 92, 0., 92., 200, -10., 10.) ; 
884   HistogramMakeUp(hMatchedDzVsStrip,((charge>0)? kRed+2 : kBlue+2), 1, "colz", "","", "strip index","dz (cm)");
885   list->AddLast(hMatchedDzVsStrip) ; 
886
887   TProfile *hMatchedDxVsCh = new TProfile(Form("hMatchedDxVsCh%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk dx vs. channel", cLabel.Data()), 157248., 0.,157248.);
888   HistogramMakeUp(hMatchedDxVsCh,((charge>0)? kRed+2 : kBlue+2), 1, "", "","", "channel index","dx (cm)");
889   list->AddLast(hMatchedDxVsCh);
890    
891   TProfile *hMatchedDzVsCh = new TProfile(Form("hMatchedDzVsCh%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk dz vs. channel", cLabel.Data()), 157248., 0.,157248.);
892   HistogramMakeUp(hMatchedDzVsCh,((charge>0)? kRed+2 : kBlue+2), 1, "", "","", "channel index","dz (cm)");
893   list->AddLast(hMatchedDzVsCh);    
894
895   return;
896 }
897
898 //----------------------------------------------------------------------------------
899 void    AliAnalysisTaskTOFqaID::AddMatchingEffHisto(TList *list, Int_t charge, TString suffix)
900 {
901   if (!list){
902     AliError("Invalid list passed as argument.");
903     return;
904   }
905   TString cLabel; 
906   if (charge == 0) cLabel.Form("all");
907   else 
908     if (charge<0) cLabel.Form("neg"); 
909     else 
910       if (charge>0) cLabel.Form("pos"); 
911
912   const Int_t nBinsX = 300;
913   Double_t xBins[nBinsX+1];
914   for (Int_t j=0;j<nBinsX+1; j++) {  
915     if (j<200) xBins[j] = j*0.025;
916     else xBins[j] = 5.0 + (j-200)*0.050;  
917   }
918
919   TH1F* hMatchedP  = new TH1F(Form("hMatchedP%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk p", cLabel.Data()), nBinsX, xBins);// 1000,0.,10.) ;  
920   HistogramMakeUp(hMatchedP,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "p (GeV/c)","tracks");
921   list->AddLast(hMatchedP) ; 
922
923   TH1F* hMatchedPt  = new TH1F(Form("hMatchedPt%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk p_{T}", cLabel.Data()), nBinsX, xBins);// 1000,0.,10.) ;  
924   HistogramMakeUp(hMatchedPt,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "p_{T} (GeV/c)","tracks");
925   list->AddLast(hMatchedPt) ; 
926
927   TH1F* hMatchedEta = new TH1F(Form("hMatchedEta%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk #eta", cLabel.Data()), 200, -1., 1.) ; 
928   HistogramMakeUp(hMatchedEta,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "#eta","tracks");
929   list->AddLast(hMatchedEta) ; 
930
931   TH1F* hMatchedPhi = new TH1F(Form("hMatchedPhi%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk #phi_{vtx}", cLabel.Data()), 72, 0., 360.) ; 
932   HistogramMakeUp(hMatchedPhi,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "#phi_{vtx} (deg)","tracks");
933   list->AddLast(hMatchedPhi) ; 
934
935   TH2F* hMatchedPtVsOutPhi  = new TH2F(Form("hMatchedPtVsOutPhi%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk p_{T} vs. #phi_{TPC out}", cLabel.Data()), 72, 0.0, 360.0, nBinsX, xBins);// 1000,0.,10.) ;  
936   HistogramMakeUp(hMatchedPtVsOutPhi,((charge>0)? kRed+2 : kBlue+2), 1, "colz", "","", "#phi_{TPC out} (deg)","p_{T} (GeV/c)");
937   list->AddLast(hMatchedPtVsOutPhi) ;
938    
939   TH1F* hPrimaryP  = new TH1F(Form("hPrimaryP%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk p", cLabel.Data()), nBinsX, xBins);// 1000,0.,10.) ;  
940   HistogramMakeUp(hPrimaryP,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "p (GeV/c)","tracks");
941   list->AddLast(hPrimaryP) ; 
942
943   TH1F* hPrimaryPt  = new TH1F(Form("hPrimaryPt%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk p_{T}", cLabel.Data()), nBinsX, xBins);// 1000,0.,10.) ;  
944   HistogramMakeUp(hPrimaryPt,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "p_{T} (GeV/c)","tracks");
945   list->AddLast(hPrimaryPt) ; 
946
947   TH1F* hPrimaryEta = new TH1F(Form("hPrimaryEta%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk #eta", cLabel.Data()), 200, -1., 1.) ; 
948   HistogramMakeUp(hPrimaryEta,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "#eta","tracks");
949   list->AddLast(hPrimaryEta) ; 
950
951   TH1F* hPrimaryPhi = new TH1F(Form("hPrimaryPhi%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk #phi_{vtx}", cLabel.Data()), 72, 0., 360.) ; 
952   HistogramMakeUp(hPrimaryPhi,((charge>0)? kRed+2 : kBlue+2), 1, "E1", "","", "#phi_{vtx} (deg)","tracks");
953   list->AddLast(hPrimaryPhi) ; 
954    
955   TH2F* hPrimaryPtVsOutPhi  = new TH2F(Form("hPrimaryPtVsOutPhi%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk p_{T} vs. #phi_{TPC out}", cLabel.Data()), 72, 0.0, 360.0, nBinsX, xBins);// 1000,0.,10.) ;  
956   HistogramMakeUp(hPrimaryPtVsOutPhi,((charge>0)? kRed+2 : kBlue+2), 1, "colz", "","", "#phi_{TPC out} (deg)","p_{T} (GeV/c)");
957   list->AddLast(hPrimaryPtVsOutPhi) ; 
958   return;
959 }
960   
961 //----------------------------------------------------------------------------------
962 void  AliAnalysisTaskTOFqaID::AddPidHisto(TList *list, Int_t charge, TString suffix)
963 {
964   //Creates histograms for monitoring TOF PID
965   if (!list){
966     AliError("Invalid list passed as argument.");
967     return;
968   }
969   TString cLabel; 
970   if (charge == 0) cLabel.Form("all");
971   else 
972     if (charge<0) cLabel.Form("neg"); 
973     else 
974       if (charge>0) cLabel.Form("pos"); 
975   
976   const Int_t nBinsX = 300;
977   Double_t xBins[nBinsX+1];
978   for (Int_t j=0;j<nBinsX+1; j++) {  
979     if (j<200) xBins[j] = j*0.025;
980     else xBins[j] = 5.0 + (j-200)*0.050;  
981   }
982
983   TH2F* hMatchedBetaVsP  = new TH2F(Form("hMatchedBetaVsP%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched trk #beta vs. p", cLabel.Data()), nBinsX, xBins, 150, 0., 1.5) ; 
984   HistogramMakeUp(hMatchedBetaVsP,((charge>0)? kRed+2 : kBlue+2), 1, "colz", "","", "p (GeV/c)","#beta");
985   list->AddLast(hMatchedBetaVsP);
986     
987   TH1F* hMatchedMass= new TH1F(Form("hMatchedMass%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched p.le M", cLabel.Data()), 500, 0., 5. );
988   HistogramMakeUp(hMatchedMass,((charge>0)? kRed+2 : kBlue+2), 1, "", "","", "M (GeV/c^{2})","entries");
989   list->AddLast(hMatchedMass);
990     
991   TH1F* hMatchedMass2= new TH1F(Form("hMatchedMass2%s_%s",suffix.Data(),cLabel.Data()), Form("%s matched p.le M^{2}", cLabel.Data()), 500, 0., 10. );
992   HistogramMakeUp(hMatchedMass2,((charge>0)? kRed+2 : kBlue+2), 1, "", "","", "M^{2} (GeV^{2}/c^{4})","entries");
993   list->AddLast(hMatchedMass2);
994
995   TH2F* hExpTimePiVsStrip = new TH2F(Form("hExpTimePiVsStrip%s_%s",suffix.Data(),cLabel.Data()),Form("%s matched trk t_{TOF}-t_{#pi,exp} vs strip",cLabel.Data()), 92, 0, 92,  fnExpTimeSmallBins, fExpTimeSmallRangeMin, fExpTimeSmallRangeMax) ; 
996   HistogramMakeUp(hExpTimePiVsStrip,((charge>0)? kRed+2 : kBlue+2), 1, "", "","", "strip (#eta)","t_{TOF}-t_{#pi,exp} [ps]");
997   list->AddLast(hExpTimePiVsStrip);
998   
999   TH2F* hExpTimePiT0Sub1GeV = new TH2F(Form("hExpTimePiT0Sub1GeV%s_%s",suffix.Data(),cLabel.Data()), Form("%s trk (0.95#leq p_{T}#leq 1.05 GeV/c) t_{TOF}-t_{#pi,exp}-t_{0}^{TOF}",cLabel.Data()), 500, 0., 500., fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1000   HistogramMakeUp(hExpTimePiT0Sub1GeV,((charge>0)? kRed+2 : kBlue+2), 1, "colz", "","","n. tracks used for t_{0}^{TOF}","t_{TOF}-t_{#pi,exp}-t_{0}^{TOF}");    
1001   list->AddLast(hExpTimePiT0Sub1GeV) ;
1002
1003   TH1F* hExpTimePiFillSub = new TH1F(Form("hExpTimePiFillSub%s_%s",suffix.Data(),cLabel.Data()), Form("%s trk t_{TOF}-t_{#pi,exp}-t_{0,fill}",cLabel.Data()), fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1004   HistogramMakeUp(hExpTimePiFillSub,((charge>0)? kRed+2 : kBlue+2), 1, "", "","","t_{TOF}-t_{#pi,exp} -t_{0,fill} [ps]","entries");    
1005   list->AddLast(hExpTimePiFillSub) ;
1006   
1007   TH1F* hExpTimePi = new TH1F(Form("hExpTimePi%s_%s",suffix.Data(),cLabel.Data()),Form("%s matched trk t_{TOF}-t_{#pi,exp}",cLabel.Data()), fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1008   HistogramMakeUp(hExpTimePi,((charge>0)? kRed+2 : kBlue+2), 1, "", "","", "t_{TOF}-t_{#pi,exp} [ps]","tracks");
1009   list->AddLast(hExpTimePi);
1010   
1011   TH2F* hExpTimePiVsP = new TH2F(Form("hExpTimePiVsP%s_%s",suffix.Data(),cLabel.Data()),Form("%s matched trk t_{TOF}-t_{#pi,exp}",cLabel.Data()), nBinsX, xBins, fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1012   HistogramMakeUp(hExpTimePiVsP,kRed+2, 1, "colz", "","", "p (GeV/c)","t_{TOF}-t_{#pi,exp} [ps]");
1013   list->AddLast(hExpTimePiVsP);
1014   
1015   TH2F* hExpTimeKaVsP = new TH2F(Form("hExpTimeKaVsP%s_%s",suffix.Data(),cLabel.Data()),Form("%s matched trk t_{TOF}-t_{K,exp}",cLabel.Data()), nBinsX, xBins, fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1016   HistogramMakeUp(hExpTimeKaVsP,kBlue+2, 1, "colz", "","", "p (GeV/c)","t_{TOF}-t_{K,exp} [ps]");
1017   list->AddLast(hExpTimeKaVsP);
1018   
1019   TH2F* hExpTimeProVsP = new TH2F(Form("hExpTimeProVsP%s_%s",suffix.Data(),cLabel.Data()),Form("%s matched trk t_{TOF}-t_{p,exp}",cLabel.Data()), nBinsX, xBins, fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1020   HistogramMakeUp(hExpTimeProVsP,kGreen+2, 1, "colz", "","", "p (GeV/c)","t_{TOF}-t_{p,exp} [ps]");
1021   list->AddLast(hExpTimeProVsP);
1022   
1023   TH2F* hTOFpidSigmaPi = new TH2F(Form("hTOFpidSigmaPi%s_%s",suffix.Data(),cLabel.Data()), Form("%s trk n#sigma^{TOF}_{#pi} vs p_{T}",cLabel.Data()), 500,0.,5.,200, -10., 10. ) ; 
1024   HistogramMakeUp(hTOFpidSigmaPi,kRed+2, 1, "colz", "","", "p (GeV/c)","n#sigma_{#pi,exp} [ps]");
1025   list->AddLast(hTOFpidSigmaPi) ;
1026   
1027   TH2F* hTOFpidSigmaKa = new TH2F(Form("hTOFpidSigmaKa%s_%s",suffix.Data(),cLabel.Data()), Form("%s trk n#sigma^{TOF}_{K} vs p_{T}",cLabel.Data()), 500, 0.,5.,200, -10., 10. ) ; 
1028   HistogramMakeUp(hTOFpidSigmaKa,kBlue+2, 1, "colz", "","", "p (GeV/c)","n#sigma_{K,exp} [ps]");
1029   list->AddLast(hTOFpidSigmaKa) ;
1030     
1031   TH2F* hTOFpidSigmaPro = new TH2F(Form("hTOFpidSigmaPro%s_%s",suffix.Data(),cLabel.Data()), Form("%s trk TOF n#sigma^{TOF}_{p} vs p_{T}",cLabel.Data()), 500, 0.,5.,200, -10., 10. ) ; 
1032   HistogramMakeUp(hTOFpidSigmaPro,kGreen+2, 1, "colz", "","","p (GeV/c)","n#sigma_{p,exp} [ps]");
1033   list->AddLast(hTOFpidSigmaPro);
1034     
1035   TH2F* hExpTimePiT0SubVsP = new TH2F(Form("hExpTimePiT0SubVsP%s_%s",suffix.Data(),cLabel.Data()), Form("%s trk t_{TOF}-t_{#pi,exp}-t_{0}^{TOF}",cLabel.Data()), nBinsX, xBins, fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1036   HistogramMakeUp(hExpTimePiT0SubVsP,kRed+2, 1, "colz", "","","p (GeV/c)","t_{TOF}-t_{#pi,exp}-t_{0}^{TOF}");
1037   list->AddLast(hExpTimePiT0SubVsP) ;
1038     
1039   TH2F* hExpTimeKaT0SubVsP = new TH2F(Form("hExpTimeKaT0SubVsP%s_%s",suffix.Data(),cLabel.Data()), Form("%s trk t_{TOF}-t_{K,exp}-t_{0}^{TOF}",cLabel.Data()), nBinsX, xBins, fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1040   HistogramMakeUp(hExpTimeKaT0SubVsP,kBlue+2, 1, "colz", "","","p (GeV/c)","t_{TOF}-t_{K,exp}-t_{0}^{TOF}");
1041   list->AddLast(hExpTimeKaT0SubVsP) ;
1042     
1043   TH2F* hExpTimeProT0SubVsP = new TH2F(Form("hExpTimeProT0SubVsP%s_%s",suffix.Data(),cLabel.Data()), Form("%s trk t_{TOF}-t_{p,exp}-t_{0}^{TOF}",cLabel.Data()), nBinsX, xBins, fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1044   HistogramMakeUp(hExpTimeProT0SubVsP,kGreen+2, 1, "colz", "","","p (GeV/c)","t_{TOF}-t_{p,exp}-t_{0}^{TOF}");
1045   list->AddLast(hExpTimeProT0SubVsP) ;
1046   
1047   TH2F* hExpTimePiVsOutPhi = new TH2F(Form("hExpTimePiVsOutPhi%s_%s",suffix.Data(),cLabel.Data()),Form("%s matched trk t_{TOF}-t_{#pi,exp} vs #phi_{TPC out}",cLabel.Data()), 72, 0.0, 360.0, fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1048   HistogramMakeUp(hExpTimePiVsOutPhi,kRed+2, 1, "colz", "","", "#phi_{TPC out} (deg)","t_{TOF}-t_{#pi,exp} [ps]");
1049   list->AddLast(hExpTimePiVsOutPhi);
1050   
1051   TH2F* hExpTimeKaVsOutPhi = new TH2F(Form("hExpTimeKaVsOutPhi%s_%s",suffix.Data(),cLabel.Data()),Form("%s matched trk t_{TOF}-t_{K,exp} vs #phi_{TPC out}",cLabel.Data()), 72, 0.0, 360.0, fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1052   HistogramMakeUp(hExpTimeKaVsOutPhi,kBlue+2, 1, "colz", "","", "#phi_{TPC out} (deg)","t_{TOF}-t_{K,exp} [ps]");
1053   list->AddLast(hExpTimeKaVsOutPhi);
1054   
1055   TH2F* hExpTimeProVsOutPhi = new TH2F(Form("hExpTimeProVsOutPhi%s_%s",suffix.Data(),cLabel.Data()),Form("%s matched trk t_{TOF}-t_{p,exp} vs #phi_{TPC out}",cLabel.Data()), 72, 0.0, 360.0, fnExpTimeBins, fExpTimeRangeMin, fExpTimeRangeMax) ; 
1056   HistogramMakeUp(hExpTimeProVsOutPhi,kGreen+2, 1, "colz", "","", "#phi_{TPC out} (deg)","t_{TOF}-t_{p,exp} [ps]");
1057   list->AddLast(hExpTimeProVsOutPhi);
1058   
1059   return;
1060 }
1061 //----------------------------------------------------------------------------------
1062 void    AliAnalysisTaskTOFqaID::AddStartTimeHisto(TList *list, TString suffix)
1063 {  
1064   //Creates histograms for monitoring T0 signal and start-time related quantities
1065   if (!list){
1066     AliError("Invalid list passed as argument.");
1067     return;
1068   }
1069   TH1F* hT0AC = new TH1F(Form("hT0AC%s",suffix.Data()), "Event timeZero from T0A&C; t_{0,AC} [ps]; events", 1000, -12500., 12500.) ; 
1070   HistogramMakeUp(hT0AC, kRed+2, 20, "", "","","","");    
1071   list->AddLast(hT0AC);
1072
1073   TH1F* hT0A = new TH1F(Form("hT0A%s",suffix.Data()), "Event timeZero from T0A; t_{0,A} [ps]; events", 1000, -12500., 12500.) ; 
1074   HistogramMakeUp(hT0A, kBlue+2, 25, "", "","","","");    
1075   list->AddLast(hT0A);
1076     
1077   TH1F* hT0C = new TH1F(Form("hT0C%s",suffix.Data()), "Event timeZero from T0C; t_{0,C} [ps]; events", 1000, -12500., 12500.) ; 
1078   HistogramMakeUp(hT0C, kGreen+2, 28, "", "","","","");    
1079   list->AddLast(hT0C);
1080     
1081   TH1F* hT0DetRes = new TH1F(Form("hT0DetRes%s",suffix.Data()), "T0 detector (T0A-T0C)/2; (T0A-T0C)/2 [ps]; events", 200, -500.,500. ) ; 
1082   HistogramMakeUp(hT0DetRes, kMagenta+1, 1, "", "","","","");    
1083   list->AddLast(hT0DetRes) ; 
1084
1085   TH1F* hT0fill = new TH1F(Form("hT0fill%s",suffix.Data()), "Event timeZero of fill; t_{0,fill} [ps]; events", 1000, -12500., 12500. ) ; 
1086   HistogramMakeUp(hT0fill, kOrange+1, 25, "", "","","","");    
1087   list->AddLast(hT0fill) ; 
1088     
1089   TH1F* hT0TOF = new TH1F(Form("hT0TOF%s",suffix.Data()), "Event timeZero estimated by TOF; t0 [ps]; events", 1000, -12500., 12500. ) ; 
1090   HistogramMakeUp(hT0TOF, kTeal-5, 21, "", "","","","");    
1091   list->AddLast(hT0TOF) ; 
1092     
1093   TH1F* hT0T0 = new TH1F(Form("hT0T0%s",suffix.Data()), "Best timeZero between AC, A, C; t_{0} [ps]; events", 1000, -12500., 12500. ) ; 
1094   HistogramMakeUp(hT0T0, kAzure+7, 26, "", "","","","");    
1095   list->AddLast(hT0T0) ; 
1096     
1097   TH1F* hT0best = new TH1F(Form("hT0best%s",suffix.Data()), "Event timeZero estimated as T0best; t0 [ps]; events", 1000, -12500., 12500.) ; 
1098   HistogramMakeUp(hT0best, kBlack, 20, "", "","","","");    
1099   list->AddLast(hT0best) ; 
1100
1101   TH1F* hT0fillRes = new TH1F(Form("hT0fillRes%s",suffix.Data()), "Resolution of fillT0; #sigma_{fillT0} [ps];events", 250, 0.,250. ) ; 
1102   HistogramMakeUp(hT0fillRes, kOrange+1, 25, "", "","","","");    
1103   list->AddLast(hT0fillRes) ; 
1104     
1105   TH1F* hT0TOFRes = new TH1F(Form("hT0TOFRes%s",suffix.Data()), "Resolution of timeZero from TOF; #sigma_{TOFT0} [ps];events", 250, 0.,250. ) ; 
1106   HistogramMakeUp(hT0TOFRes, kTeal-5, 21, "", "","","","");    
1107   list->AddLast(hT0TOFRes) ; 
1108
1109   TH1F* hT0T0Res = new TH1F(Form("hT0T0Res%s",suffix.Data()), "Resolution of timeZero from T0;#sigma_{T0T0}  [ps];events", 250, -0., 250. ) ; 
1110   HistogramMakeUp(hT0T0Res, kAzure+7, 26, "", "","","","");    
1111   list->AddLast(hT0T0Res) ; 
1112   
1113   TH1F* hT0bestRes = new TH1F(Form("hT0bestRes%s",suffix.Data()), "Resolution of bestT0; #sigma_{bestT0} [ps];events", 250, 0.,250. ) ; 
1114   HistogramMakeUp(hT0bestRes, kBlack, 20, "", "","","","");    
1115   list->AddLast(hT0bestRes) ; 
1116
1117   TH2F* hT0TOFvsNtrk = new TH2F(Form("hT0TOFvsNtrk%s",suffix.Data()), "Event timeZero estimated by TOF vs. number of tracks in event;TOF-matching tracks; t0 [ps]", 100, 0., 100., 500,-2500.,2500. ) ; 
1118   HistogramMakeUp(hT0TOFvsNtrk, kTeal-5, 1, "colz", "","","","");    
1119   list->AddLast(hT0TOFvsNtrk) ;
1120   
1121   TH2F* hEventT0MeanVsVtx = new TH2F(Form("hEventT0MeanVsVtx%s",suffix.Data()), "T0 detector: mean vs vertex ; (t0_{A}-t0_{C})/2 [ns]; (t0_{A}+t0_{C})/2 [ns]; events", 50, -25., 25., 50, -25., 25. ) ; 
1122   HistogramMakeUp(hEventT0MeanVsVtx, kBlue+2, 1, "colz", "","","","");    
1123   list->AddLast(hEventT0MeanVsVtx) ;
1124     
1125   TH2F* hEventV0MeanVsVtx = new TH2F(Form("hEventV0MeanVsVtx%s",suffix.Data()), "V0 detector: mean vs vertex ; (V0_{A}-V0_{C})/2 [ns]; (V0_{A}+V0_{C})/2 [ns]; events", 50, -25., 25., 50, -25., 25.) ; 
1126   HistogramMakeUp(hEventV0MeanVsVtx, kBlack, 1, "colz", "","","","");    
1127   list->AddLast(hEventV0MeanVsVtx) ;
1128   
1129   const Double_t startTimeMomBins[13]={ 0.0, 0.3, 0.5, 0.6, 0.7, 0.8, 0.9, 1., 1.2, 1.5, 2., 3., 10.};
1130     
1131   TH2F* hStartTimeMaskMatched = new TH2F(Form("hStartTimeMaskMatched%s",suffix.Data()),"Start Time Mask vs p bin for matched tracks; p(GeV/c);", 12, startTimeMomBins, 8,0.,8.);
1132   hStartTimeMaskMatched->GetYaxis()->SetBinLabel(1,"fill_t0");
1133   hStartTimeMaskMatched->GetYaxis()->SetBinLabel(2,"tof_t0");
1134   hStartTimeMaskMatched->GetYaxis()->SetBinLabel(3,"T0AC");
1135   hStartTimeMaskMatched->GetYaxis()->SetBinLabel(4,"T0AC & tof_t0");
1136   hStartTimeMaskMatched->GetYaxis()->SetBinLabel(5,"T0A");
1137   hStartTimeMaskMatched->GetYaxis()->SetBinLabel(6,"T0A & tof_t0");
1138   hStartTimeMaskMatched->GetYaxis()->SetBinLabel(7,"T0C");
1139   hStartTimeMaskMatched->GetYaxis()->SetBinLabel(8,"T0C & tof_t0");
1140   HistogramMakeUp(hStartTimeMaskMatched, kRed+2, 1, "colz", "","","","");    
1141   list->AddLast(hStartTimeMaskMatched);
1142     
1143   TH2F* hStartTimeMask = new TH2F(Form("hStartTimeMask%s",suffix.Data()),"Start Time Mask vs p bin for primary tracks; p(GeV/c);", 12, startTimeMomBins, 8,0.,8.);
1144   hStartTimeMask->GetYaxis()->SetBinLabel(1,"fill_t0");
1145   hStartTimeMask->GetYaxis()->SetBinLabel(2,"tof_t0");
1146   hStartTimeMask->GetYaxis()->SetBinLabel(3,"T0AC");
1147   hStartTimeMask->GetYaxis()->SetBinLabel(4,"T0AC & tof_t0");
1148   hStartTimeMask->GetYaxis()->SetBinLabel(5,"T0A");
1149   hStartTimeMask->GetYaxis()->SetBinLabel(6,"T0A & tof_t0");
1150   hStartTimeMask->GetYaxis()->SetBinLabel(7,"T0C");
1151   hStartTimeMask->GetYaxis()->SetBinLabel(8,"T0C & tof_t0");
1152   HistogramMakeUp(hStartTimeMask, kRed+2, 1, "colz", "","","","");    
1153   list->AddLast(hStartTimeMask);
1154
1155   return;
1156 }
1157 //----------------------------------------------------------------------------------
1158 void AliAnalysisTaskTOFqaID::AddTrdHisto()
1159 {
1160   //Creates histograms for monitoring TOF base quantities wrt TRD/no TRD selection
1161   if (!fHlistTRD){
1162     AliError("Invalid TRD list");
1163     return;
1164   }
1165
1166   if (fEnableChargeSplit) {
1167     AddMatchingEffHisto(fHlistTRD, 1, "_noTrd");
1168     AddMatchingEffHisto(fHlistTRD, -1, "_noTrd");
1169     AddMatchingEffHisto(fHlistTRD, 1, "_Trd");
1170     AddMatchingEffHisto(fHlistTRD, -1, "_Trd");
1171     
1172     AddPidHisto(fHlistTRD, 1, "_noTrd");
1173     AddPidHisto(fHlistTRD, -1, "_noTrd");
1174     AddPidHisto(fHlistTRD, 1, "_Trd");
1175     AddPidHisto(fHlistTRD, -1, "_Trd");
1176   } else {
1177     AddMatchingEffHisto(fHlistTRD, 0, "_noTrd");
1178     AddMatchingEffHisto(fHlistTRD, 0, "_Trd");
1179     AddPidHisto(fHlistTRD, 0, "_noTrd");
1180     AddPidHisto(fHlistTRD, 0, "_Trd");
1181   }
1182
1183   return;
1184 }
1185  
1186
1187 //----------------------------------------------------------------------------------
1188 void AliAnalysisTaskTOFqaID::AddTofTrgHisto(TString suffix)
1189 {
1190   //defines histo with trigger info
1191   if (!fHlistTrigger){
1192     AliError("Invalid TOF trigger list");
1193     return;
1194   }
1195   
1196   TH1I* hFiredMaxipad = new TH1I(Form("hFiredMaxipad%s",suffix.Data()), Form("Fired maxipad per event"), 1584, 0, 1584);  
1197   HistogramMakeUp(hFiredMaxipad, kBlue+2, 1, "E1", "","", "N_{maxipad}","events");
1198   fHlistTrigger->AddLast(hFiredMaxipad);
1199   
1200   TH1I* hFiredReadoutPad = new TH1I(Form("hFiredReadoutPad%s",suffix.Data()), Form("Fired readout pad per event"), 153000, 0, 153000);  
1201   HistogramMakeUp(hFiredReadoutPad, kRed+2, 1, "E1", "","", "N_{pad}","events");
1202   fHlistTrigger->AddLast(hFiredReadoutPad);
1203   
1204   TH1I* hFiredReadoutTrgPad = new TH1I(Form("hFiredReadoutTrgPad%s",suffix.Data()), Form("Fired readout pad in trg window"), 153000, 0, 153000);  
1205   HistogramMakeUp(hFiredReadoutTrgPad, kBlack, 1, "E1", "","", "N_{pad} in trg window","events");
1206   fHlistTrigger->AddLast(hFiredReadoutTrgPad);
1207   
1208   TH2I* hFiredMaxipadVsTrgPad = new TH2I(Form("hFiredMaxipadVsTrgPad%s",suffix.Data()), Form("Fired maxipad vs pads in trg window per event"), 100, 0, 100, 100, 0, 100);  
1209   HistogramMakeUp(hFiredMaxipadVsTrgPad, kBlue+2, 1, "colz", "","", "N_{pad} in trg window","N_{maxipad}");
1210   fHlistTrigger->AddLast(hFiredMaxipadVsTrgPad);
1211   
1212   TH2I* hTrgMap = new TH2I(Form("hTrgMap%s",suffix.Data()), Form("Map of fired maxipads"), 72, 0, 72, 23, 0, 23);  
1213   HistogramMakeUp(hTrgMap, kBlue+2, 1, "colz", "","", "LTM","maxipad");
1214   fHlistTrigger->AddLast(hTrgMap);
1215   
1216   return;
1217 }
1218
1219 //----------------------------------------------------------------------------------
1220 void AliAnalysisTaskTOFqaID::FillTofBaseHisto(AliESDtrack * track, Int_t charge, TString suffix)
1221 {
1222   //fill histo with TOF base quantities
1223   if (!track) return;
1224   
1225   //  Double_t tofTime=track->GetTOFsignal();//in ps
1226   Double_t tofTimeRaw=track->GetTOFsignalRaw();//in ps
1227   Double_t tofToT=track->GetTOFsignalToT(); //in ps
1228   Int_t channel=track->GetTOFCalChannel(); 
1229   Int_t volId[5]; //(sector, plate,strip,padZ,padX)
1230   AliTOFGeometry::GetVolumeIndices(channel,volId);
1231   TString cLabel;
1232   if (charge == 0) cLabel.Form("all");
1233   else 
1234     if (charge<0) cLabel.Form("neg"); 
1235     else 
1236       if (charge>0) cLabel.Form("pos"); 
1237
1238   ((TH1F*)fHlist->FindObject(Form("hTime%s_%s",suffix.Data(),cLabel.Data())))->Fill(fTof); //ns
1239   ((TH1F*)fHlist->FindObject(Form("hRawTime%s_%s",suffix.Data(),cLabel.Data())))->Fill(tofTimeRaw*1E-3); //ns
1240   ((TH1F*)fHlist->FindObject(Form("hTot%s_%s",suffix.Data(),cLabel.Data())))->Fill(tofToT);
1241   ((TH1F*)fHlist->FindObject(Form("hMatchedL%s_%s", suffix.Data(), cLabel.Data())))->Fill(fL);      
1242   ((TH2F*)fHlist->FindObject(Form("hMatchedDxVsPt%s_%s",suffix.Data(),cLabel.Data())))->Fill(fPt,track->GetTOFsignalDx());
1243   ((TH2F*)fHlist->FindObject(Form("hMatchedDzVsStrip%s_%s",suffix.Data(),cLabel.Data())))->Fill((Int_t)GetStripIndex(volId),track->GetTOFsignalDz());
1244   ((TProfile*)fHlist->FindObject(Form("hMatchedDxVsCh%s_%s",suffix.Data(),cLabel.Data())))->Fill(channel,track->GetTOFsignalDx());
1245   ((TProfile*)fHlist->FindObject(Form("hMatchedDzVsCh%s_%s",suffix.Data(),cLabel.Data())))->Fill(channel,track->GetTOFsignalDz());
1246   
1247   return;
1248 }
1249 //----------------------------------------------------------------------------------
1250 void AliAnalysisTaskTOFqaID::FillPrimaryTrkHisto(Int_t charge, TString suffix)
1251 {
1252   // fill histos with primary tracks info
1253   // => denominator for matching efficiency
1254   TString cLabel; 
1255   if (charge == 0) cLabel.Form("all");
1256   else 
1257     if (charge<0) cLabel.Form("neg"); 
1258     else 
1259       if (charge>0) cLabel.Form("pos"); 
1260   
1261   if (suffix.Contains("Trd")) {
1262     ((TH1F*)fHlistTRD->FindObject(Form("hPrimaryP%s_%s",suffix.Data(),cLabel.Data())))->Fill(fP); 
1263     ((TH1F*)fHlistTRD->FindObject(Form("hPrimaryPt%s_%s",suffix.Data(),cLabel.Data())))->Fill(fPt); 
1264     ((TH2F*)fHlistTRD->FindObject(Form("hPrimaryPtVsOutPhi%s_%s",suffix.Data(),cLabel.Data())))->Fill(fTPCOuterPhi,fPt);
1265     if (fPt>=fMatchingMomCut) {
1266       ((TH1F*)fHlistTRD->FindObject(Form("hPrimaryEta%s_%s",suffix.Data(),cLabel.Data())))->Fill(fEta);
1267       ((TH1F*)fHlistTRD->FindObject(Form("hPrimaryPhi%s_%s",suffix.Data(),cLabel.Data())))->Fill(fPhi);
1268     }
1269   } else {
1270     ((TH1F*)fHlist->FindObject(Form("hPrimaryP%s_%s",suffix.Data(),cLabel.Data())))->Fill(fP); 
1271     ((TH1F*)fHlist->FindObject(Form("hPrimaryPt%s_%s",suffix.Data(),cLabel.Data())))->Fill(fPt); 
1272     ((TH2F*)fHlist->FindObject(Form("hPrimaryPtVsOutPhi%s_%s",suffix.Data(),cLabel.Data())))->Fill(fTPCOuterPhi,fPt); 
1273     if (fPt>=fMatchingMomCut) {
1274       ((TH1F*)fHlist->FindObject(Form("hPrimaryEta%s_%s",suffix.Data(),cLabel.Data())))->Fill(fEta);
1275       ((TH1F*)fHlist->FindObject(Form("hPrimaryPhi%s_%s",suffix.Data(),cLabel.Data())))->Fill(fPhi);
1276     }
1277   }
1278   return;
1279 }
1280 //----------------------------------------------------------------------------------
1281 void AliAnalysisTaskTOFqaID::FillMatchedTrkHisto(Int_t charge, TString suffix)
1282 {
1283   //get matched tracks variables (matching cut to be applied externally)
1284   //=> numerator for matching efficiency
1285   TString cLabel; 
1286   if (charge == 0) cLabel.Form("all");
1287   else 
1288     if (charge<0) cLabel.Form("neg"); 
1289     else 
1290       if (charge>0) cLabel.Form("pos"); 
1291   
1292   if (suffix.Contains("Trd")) { 
1293     ((TH1F*)fHlistTRD->FindObject(Form("hMatchedP%s_%s",suffix.Data(),cLabel.Data())))->Fill(fP); 
1294     ((TH1F*)fHlistTRD->FindObject(Form("hMatchedPt%s_%s",suffix.Data(),cLabel.Data())))->Fill(fPt); 
1295     ((TH2F*)fHlistTRD->FindObject(Form("hMatchedPtVsOutPhi%s_%s",suffix.Data(),cLabel.Data())))->Fill(fTPCOuterPhi,fPt);
1296     if (fPt>=fMatchingMomCut) {
1297       ((TH1F*)fHlistTRD->FindObject(Form("hMatchedEta%s_%s",suffix.Data(),cLabel.Data())))->Fill(fEta);
1298       ((TH1F*)fHlistTRD->FindObject(Form("hMatchedPhi%s_%s",suffix.Data(),cLabel.Data())))->Fill(fPhi);
1299     }
1300   } else {
1301     ((TH1F*)fHlist->FindObject(Form("hMatchedP%s_%s",suffix.Data(),cLabel.Data())))->Fill(fP); 
1302     ((TH1F*)fHlist->FindObject(Form("hMatchedPt%s_%s",suffix.Data(),cLabel.Data())))->Fill(fPt); 
1303     ((TH2F*)fHlist->FindObject(Form("hMatchedPtVsOutPhi%s_%s",suffix.Data(),cLabel.Data())))->Fill(fTPCOuterPhi,fPt);
1304     if (fPt>=fMatchingMomCut) {
1305       ((TH1F*)fHlist->FindObject(Form("hMatchedEta%s_%s",suffix.Data(),cLabel.Data())))->Fill(fEta);
1306       ((TH1F*)fHlist->FindObject(Form("hMatchedPhi%s_%s",suffix.Data(),cLabel.Data())))->Fill(fPhi);
1307     }
1308   }
1309   return;
1310 }
1311
1312 //----------------------------------------------------------------------------------
1313 void AliAnalysisTaskTOFqaID::FillPidHisto(AliESDtrack * track, Int_t charge, TString suffix)
1314 {
1315   //basic PID performance check
1316   if (fTof<=0) {
1317     printf("WARNING: track with negative TOF time found! Skipping this track for PID checks\n");
1318     return;
1319   }
1320   if (fL<=0){
1321     printf("WARNING: track with negative length found!Skipping this track for PID checks\n");
1322     return;
1323   }
1324   if (!track) return;
1325   
1326   TString cLabel; 
1327   if (charge == 0) cLabel.Form("all");
1328   else 
1329     if (charge<0) cLabel.Form("neg"); 
1330     else 
1331       if (charge>0) cLabel.Form("pos"); 
1332   
1333   //calculate beta
1334   Double_t c=TMath::C()*1.E-9;// m/ns
1335   Double_t mass=0.; //GeV
1336   Double_t length=fL*0.01; // in meters
1337   Double_t tof=fTof*c;
1338   Double_t beta=length/tof;
1339   Double_t fact= (tof/length)*(tof/length) -1.;
1340   Double_t fP2 = fP*fP;
1341   
1342   if(fact<=0) {
1343     mass = -fP*TMath::Sqrt(-fact);
1344   } else { 
1345     mass = fP*TMath::Sqrt(fact); 
1346   }
1347   
1348   if (suffix.Contains("Trd")) {
1349     ((TH2F*) fHlistTRD->FindObject(Form("hMatchedBetaVsP%s_%s",suffix.Data(),cLabel.Data())))->Fill(fP,beta);
1350     ((TH1F*) fHlistTRD->FindObject(Form("hMatchedMass%s_%s",suffix.Data(),cLabel.Data())))->Fill(mass);
1351     ((TH1F*) fHlistTRD->FindObject(Form("hMatchedMass2%s_%s",suffix.Data(),cLabel.Data())))->Fill(mass*mass);
1352   } else {
1353     ((TH2F*) fHlistPID->FindObject(Form("hMatchedBetaVsP%s_%s",suffix.Data(),cLabel.Data())))->Fill(fP,beta);
1354     ((TH1F*) fHlistPID->FindObject(Form("hMatchedMass%s_%s",suffix.Data(),cLabel.Data())))->Fill(mass);
1355     ((TH1F*) fHlistPID->FindObject(Form("hMatchedMass2%s_%s",suffix.Data(),cLabel.Data())))->Fill(mass*mass);
1356   }
1357   
1358   //PID sigmas
1359   Bool_t isValidBeta[AliPID::kSPECIES]={0,0,0,0,0};
1360   for (Int_t specie = 0; specie < AliPID::kSPECIES; specie++){
1361     fSigmaSpecie[specie] = fESDpid->GetTOFResponse().GetExpectedSigma(fP, fTrkExpTimes[specie], AliPID::ParticleMass(specie));
1362     beta=1/TMath::Sqrt(1+AliPID::ParticleMass(specie)*AliPID::ParticleMass(specie)/(fP2));
1363     if (beta>0) {
1364       fThExpTimes[specie]=length*1.E3/(beta*c);//ps
1365       isValidBeta[specie]=kTRUE;
1366     } else {
1367       fThExpTimes[specie]=1E-10;
1368       isValidBeta[specie]=kFALSE;
1369     }
1370   }
1371   Float_t timeZeroTOF = (Float_t) fESDpid->GetTOFResponse().GetStartTime(fPt);
1372   Double_t tofps=fTof*1E3;//ps for t-texp
1373   Int_t channel=track->GetTOFCalChannel(); 
1374   Int_t volId[5]; //(sector, plate,strip,padZ,padX)
1375   AliTOFGeometry::GetVolumeIndices(channel,volId);
1376   Char_t partName[3][4] = {"Pi","Ka","Pro"}; 
1377   
1378   if (suffix.Contains("Trd")) {
1379     //fill histos for pion only
1380     ((TH2F*)fHlistTRD->FindObject(Form("hExpTimePiVsStrip%s_%s",suffix.Data(),cLabel.Data())))->Fill((Int_t)GetStripIndex(volId),tofps-fTrkExpTimes[AliPID::kPion]);//ps
1381     ((TH1F*)fHlistTRD->FindObject(Form("hExpTimePi%s_%s",suffix.Data(),cLabel.Data())))->Fill(tofps-fTrkExpTimes[AliPID::kPion]);//ps   
1382     if (ComputeTimeZeroByTOF1GeV() && (fPt>0.95) && (fPt<1.05) ){
1383       ((TH2F*)fHlistTRD->FindObject(Form("hExpTimePiT0Sub1GeV%s_%s",suffix.Data(),cLabel.Data())))->Fill(fMyTimeZeroTOFtracks,tofps-fMyTimeZeroTOF-fTrkExpTimes[AliPID::kPion]);
1384     }
1385     //fill sigmas and deltas for each specie
1386     for (Int_t specie = AliPID::kPion; specie <= AliPID::kProton; specie++){
1387       if (isValidBeta[specie]){
1388         ((TH2F*)fHlistTRD->FindObject(Form("hExpTime%sVsP%s_%s",partName[specie-2], suffix.Data(),cLabel.Data())))->Fill(fP, tofps-fTrkExpTimes[specie]);
1389         ((TH2F*)fHlistTRD->FindObject(Form("hTOFpidSigma%s%s_%s",partName[specie-2], suffix.Data(),cLabel.Data())))->Fill(fPt, (tofps-fTrkExpTimes[specie])/fSigmaSpecie[specie]);
1390         ((TH2F*)fHlistTRD->FindObject(Form("hExpTime%sT0SubVsP%s_%s",partName[specie-2], suffix.Data(),cLabel.Data())))->Fill(fP,tofps-fTrkExpTimes[specie]-timeZeroTOF);  
1391         ((TH2F*)fHlistTRD->FindObject(Form("hExpTime%sVsOutPhi%s_%s",partName[specie-2], suffix.Data(),cLabel.Data())))->Fill(fTPCOuterPhi,tofps-fTrkExpTimes[specie]-timeZeroTOF);
1392           
1393       }// end check on beta
1394     }
1395   } else { 
1396     
1397     //fill histos for pion only
1398     ((TH2F*)fHlistPID->FindObject(Form("hExpTimePiVsStrip%s_%s",suffix.Data(),cLabel.Data())))->Fill((Int_t)GetStripIndex(volId),tofps-fTrkExpTimes[AliPID::kPion]);//ps
1399     ((TH1F*)fHlistPID->FindObject(Form("hExpTimePi%s_%s",suffix.Data(),cLabel.Data())))->Fill(tofps-fTrkExpTimes[AliPID::kPion]);//ps    
1400     if (ComputeTimeZeroByTOF1GeV() && (fPt>0.95) && (fPt<1.05) ){
1401       ((TH2F*)fHlistPID->FindObject(Form("hExpTimePiT0Sub1GeV%s_%s",suffix.Data(),cLabel.Data())))->Fill(fMyTimeZeroTOFtracks,tofps-fMyTimeZeroTOF-fTrkExpTimes[AliPID::kPion]);
1402     }
1403     //fill sigmas and deltas for each specie
1404     for (Int_t specie = AliPID::kPion; specie <= AliPID::kProton; specie++){
1405       if (isValidBeta[specie]){
1406         ((TH2F*)fHlistPID->FindObject(Form("hExpTime%sVsP%s_%s",partName[specie-2], suffix.Data(),cLabel.Data())))->Fill(fP, tofps-fTrkExpTimes[specie]);
1407         ((TH2F*)fHlistPID->FindObject(Form("hTOFpidSigma%s%s_%s",partName[specie-2], suffix.Data(),cLabel.Data())))->Fill(fPt, (tofps-fTrkExpTimes[specie])/fSigmaSpecie[specie]);
1408         ((TH2F*)fHlistPID->FindObject(Form("hExpTime%sT0SubVsP%s_%s",partName[specie-2], suffix.Data(),cLabel.Data())))->Fill(fP,tofps-fTrkExpTimes[specie]-timeZeroTOF);  
1409         ((TH2F*)fHlistPID->FindObject(Form("hExpTime%sVsOutPhi%s_%s",partName[specie-2], suffix.Data(),cLabel.Data())))->Fill(fTPCOuterPhi,tofps-fTrkExpTimes[specie]-timeZeroTOF);
1410       }// end check on beta
1411     } 
1412  
1413   }
1414   
1415   //re-set response kFILL_T0 to check post-alignment wih OADB
1416   fESDpid->SetTOFResponse(fESD,AliESDpid::kFILL_T0);//(fill_t0, tof_t0, t0_t0, best_t0)
1417   Float_t startTimeFill=fESDpid->GetTOFResponse().GetStartTime(fP); //timeZero for bin pT>10GeV/c
1418   if (suffix.Contains("Trd"))
1419     ((TH1F*)fHlistTRD->FindObject(Form("hExpTimePiFillSub%s_%s",suffix.Data(),cLabel.Data())))->Fill(tofps-fTrkExpTimes[AliPID::kPion]-startTimeFill);//ps
1420   else 
1421     ((TH1F*)fHlistPID->FindObject(Form("hExpTimePiFillSub%s_%s",suffix.Data(),cLabel.Data())))->Fill(tofps-fTrkExpTimes[AliPID::kPion]-startTimeFill);//ps
1422  
1423   // if (fEnableAdvancedCheck && (fPt<1.)) {
1424   //   Double_t pos[3]={0.,0.,0.};
1425   //   track->GetXYZAt(378.,5.,pos);
1426   //   if ((pos[0]==0.)&&(pos[1]==0.)&&(pos[2]==0.))continue;
1427   
1428   //   Double_t phiTOF=TMath::ATan2(pos[1],pos[0])*TMath::RadToDeg();
1429   //   if (phiTOF<0) phiTOF+= (2*TMath::Pi()*TMath::RadToDeg());
1430   
1431   //   //fill t-texp vs phi@TOF
1432   //    if ((phiOuterTPC<=75) || ((phiOuterTPC>=125)&&(phiOuterTPC<=235)) || (phiOuterTPC>=305) ) { //TRD sectors 2012
1433   //    if ( ((phiOuterTPC>=85)&&(phiOuterTPC<=115)) || ((phiOuterTPC>=245)&&(phiOuterTPC<=295)) ) {//no TRD sectors 2012
1434   // }
1435   return;      
1436 }
1437 //----------------------------------------------------------------------------------
1438 void AliAnalysisTaskTOFqaID::FillStartTimeHisto(TString suffix)
1439 {
1440   //fill start time histo
1441   if (!fESD) {
1442     AliError("Invalid event object");
1443     return;
1444   }
1445   // info from V0 detector QA 
1446   AliESDVZERO * vzero = fESD->GetVZEROData();
1447   Float_t V0Atime = vzero->GetV0ATime();
1448   Float_t V0Ctime = vzero->GetV0CTime(); 
1449   ((TH2F*)fHlistTimeZero->FindObject(Form("hEventV0MeanVsVtx%s",suffix.Data())))->Fill((V0Atime-V0Ctime)*0.5,(V0Atime+V0Ctime)*0.5);
1450   
1451   // info from T0 detector QA 
1452   for (Int_t j=0;j<3;j++){
1453     fT0[j]= (Float_t) fESD->GetT0TOF(j);//ps
1454     if (fT0[j]>90000.) fT0[j]=99999.;//fix old default values to the new one
1455   }
1456   
1457   Float_t t0cut = 90000.; 
1458   //Float_t t0cut =3 * t0spread; //use this cut to check t0 used in tof response
1459   // if(t0cut < 500) t0cut = 500;
1460   
1461   if(TMath::Abs(fT0[1]) < t0cut && TMath::Abs(fT0[2]) < t0cut ) {
1462     //&& TMath::Abs(fT0[2]-fT0[1]) < 500)  //add this condition to check t0 used in tof response
1463     ((TH1F*)fHlistTimeZero->FindObject(Form("hT0DetRes%s",suffix.Data())))->Fill((fT0[2]-fT0[1])*0.5);
1464     ((TH1F*)fHlistTimeZero->FindObject(Form("hT0AC%s",suffix.Data())))->Fill(fT0[0]);  
1465     ((TH2F*)fHlistTimeZero->FindObject(Form("hEventT0MeanVsVtx%s",suffix.Data())))->Fill( ((fT0[2]-fT0[1])*0.5e-3), ((fT0[2]+fT0[1])*0.5e-3) );
1466   } 
1467   if(TMath::Abs(fT0[1]) < t0cut){
1468     ((TH1F*)fHlistTimeZero->FindObject(Form("hT0A%s",suffix.Data())))->Fill(fT0[1]);   
1469   }
1470   if(TMath::Abs(fT0[2]) < t0cut){
1471     ((TH1F*)fHlistTimeZero->FindObject(Form("hT0C%s",suffix.Data())))->Fill(fT0[2]);
1472   }
1473   
1474   //  event timeZero QA via AliESDpid::SetTOFResponse() 
1475   Double_t timeZero[4]={99999.,99999.,99999.,99999.};
1476   Double_t timeZeroRes[4]={99999.,99999.,99999.,99999.}; 
1477   
1478   TString timeZeroHisto[4]={"hT0fill","hT0TOF","hT0T0","hT0best"};
1479   TString timeZeroHistoRes[4]={"hT0fillRes","hT0TOFRes","hT0T0Res","hT0bestRes"};
1480   for (Int_t j=0;j<4;j++){
1481     timeZeroHisto[j].Append(suffix.Data());
1482     timeZeroHistoRes[j].Append(suffix.Data());
1483     fESDpid->SetTOFResponse(fESD, (AliESDpid::EStartTimeType_t) j);//(fill_t0, tof_t0, t0_t0, best_t0)
1484     timeZero[j]=fESDpid->GetTOFResponse().GetStartTime(10.); //timeZero for bin pT>10GeV/c
1485     timeZeroRes[j]=fESDpid->GetTOFResponse().GetStartTimeRes(10.); //timeZero for bin pT>10GeV/c
1486     ((TH1F*)(fHlistTimeZero->FindObject(timeZeroHisto[j].Data())))->Fill(timeZero[j]);
1487     ((TH1F*)(fHlistTimeZero->FindObject(timeZeroHistoRes[j].Data())))->Fill(timeZeroRes[j]);
1488   }
1489   ((TH2F*)fHlistTimeZero->FindObject("hT0TOFvsNtrk"))->Fill(fNTOFtracks[0],timeZero[AliESDpid::kTOF_T0]);
1490    
1491   //response set to best_t0 by previous loop
1492   FillStartTimeMaskHisto(suffix.Data());
1493
1494   return;
1495 }
1496 //----------------------------------------------------------------------------------
1497 void AliAnalysisTaskTOFqaID::FillTrdHisto(AliESDtrack * track, Int_t charge)
1498 {
1499   //fill histograms for TRD/noTRD
1500   if (!track){
1501     AliError("Invalid track object");
1502     return;
1503   }
1504   
1505   if (IsInTRD(track)){
1506     FillPrimaryTrkHisto(charge,"_Trd");
1507     if (IsTPCTOFMatched(track)) {      
1508       FillMatchedTrkHisto(charge,"_Trd");
1509       FillPidHisto(track,charge, "_Trd");
1510     }
1511   } else {
1512     FillPrimaryTrkHisto(charge,"_noTrd");    
1513     if (IsTPCTOFMatched(track)) {      
1514       FillMatchedTrkHisto(charge,"_noTrd");
1515       FillPidHisto(track, charge, "_noTrd");
1516     }
1517   }
1518   return;
1519 }
1520 //----------------------------------------------------------------------------------
1521 void AliAnalysisTaskTOFqaID::FillTofTrgHisto(TString suffix)
1522 {
1523   //fills histo with trigger info
1524   if (!fHlistTrigger){
1525     AliError("Invalid TOF trigger list");
1526     return;
1527   }
1528   if (!fTOFHeader) {
1529     AliWarning("Invalid AliTOFHeader object - cannot fill trg histo");
1530     return;    
1531   }
1532   
1533   Int_t nPad = fTOFHeader->GetNumberOfTOFclusters(); //all fired readout pads
1534   Int_t nTrgPad = fTOFHeader->GetNumberOfTOFtrgPads();// fired readout pads in the trigger window
1535   Int_t nMaxiPad = fTOFHeader->GetNumberOfTOFmaxipad(); //fired maxipads
1536   
1537   // update histo with fired macropads
1538   AliTOFTriggerMask *trgMask = fTOFHeader->GetTriggerMask();
1539   for(Int_t j=0;j<72;j++){
1540     for(Int_t i=22;i>=0;i--){
1541       if(trgMask->IsON(j,i))
1542         ((TH1I*)fHlistTrigger->FindObject(Form("hTrgMap%s",suffix.Data())))->Fill(j+1,i+1); 
1543     }   
1544   }
1545   ((TH1I*)fHlistTrigger->FindObject(Form("hFiredMaxipad%s",suffix.Data())))->Fill(nMaxiPad);
1546   ((TH1I*)fHlistTrigger->FindObject(Form("hFiredReadoutPad%s",suffix.Data())))->Fill(nPad);
1547   ((TH1I*)fHlistTrigger->FindObject(Form("hFiredReadoutTrgPad%s",suffix.Data())))->Fill(nTrgPad);
1548   ((TH2I*)fHlistTrigger->FindObject(Form("hFiredMaxipadVsTrgPad%s",suffix.Data())))->Fill(nTrgPad,nMaxiPad);
1549   
1550   return;
1551 }
1552
1553 #endif