]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/QA/tasks/macros/drawTHnSparse.C
- added message for the case a canvas is not created when the entries of the THnSpars...
[u/mrichter/AliRoot.git] / HLT / QA / tasks / macros / drawTHnSparse.C
1 // $Id$
2 /*
3  * Drawing macro for reading the THnSparse output of the 
4  * HLT/QA/tasks/AliAnalysisTaskHLTCentralBarrel.cxx task.
5  * 
6  * The cuts are user defined around lines 160-165 as arguments of the 
7  * function cutStsudies(...).
8  * 
9  * The input file contains information about the run number
10  * and date that will appear in the canvas title.
11  * 
12  * The cuts are turned into strings and incorporated in the
13  * name of the output file, which contains canvases with event
14  * and track properties for HLT and offline.
15  *  
16  * Since the run information is available, there will be a new
17  * folder created and the canvas ROOT files will be saved in there.
18  *
19  * The macro should be compiled before running:
20  *
21  * root[0] .L drawTHnSparse.C++
22  * root[1] drawTHnSparse("HLT-OFFLINE-CentralBarrel-comparison.root")
23  *
24  * @ingroup alihlt_qa
25  * @author Kalliopi.Kanaki@ift.uib.no 
26  */
27
28 #if !defined(__CINT__) || defined(__MAKECINT__)
29 #include "TSystem.h"
30 #include "TROOT.h"
31 #include "TFile.h"
32 #include "TString.h"
33 #include "TList.h"
34 #include "THnSparse.h"
35 #include "TCanvas.h"
36 #include "TText.h"
37 #include "TPaveText.h"
38 #include "TPaveStats.h"
39 #include "TH1D.h"
40 #include "TH2D.h"
41 #include "TH3D.h"
42 #include "TLegend.h"
43 #include "TStyle.h"
44 #include "TPad.h"
45 #include <iostream>
46 #include <cstdlib>
47 using std::endl;
48 #endif
49
50 //---------- forward declerations ---------------//
51 TString cutStudies( TString folder,  THnSparse* htrackHLT, THnSparse* htrackOFF, TText* hText,
52                     double minEta,   double maxEta,
53                     int minTrackMult,int maxTrackMult,
54                     double minPt,    double maxPt,
55                     double minDCAr,  double maxDCAr,
56                     double minDCAz,  double maxDCAz,
57                     int minTPCclus,  int maxTPCclus,
58                     int minITSclus,  int maxITSclus,
59                     int vs,          float vz,
60                     float minCent,   float maxCent
61                   );
62 void printStats(TH1D *hlt, TH1D *off);
63 void defineYaxisMax(TH1D *h1, TH1D *h2);
64 void printLegend(TH1D *hlt, TH1D *off);
65 void plot2D( THnSparse* h,     TText *hText,   TString folder,
66              double minEta,    double maxEta,
67              double minPt,     double maxPt,
68              double minDCAr,   double maxDCAr,
69              double minDCAz,   double maxDCAz,
70              int minTPCclus,   int maxTPCclus,
71              int minITSclus,   int maxITSclus, 
72              int minTrackMult, int maxTrackMult, 
73              int vs,           float vz,
74              float minCent,    float maxCent
75             );
76 void plotEventQuantities(THnSparse* heventHLT, THnSparse* heventOFF, TText* hText, TString folder);
77 TString fix1DTitle(const char* c);
78 TString fix2DTitle(const char* c1, const char* c2);
79 TString cutsToString( double minEta,    double maxEta,
80                       double minPt,     double maxPt,
81                       double minDCAr,   double maxDCAr,
82                       double minDCAz,   double maxDCAz,
83                       int minTPCclus,   int maxTPCclus,
84                       int minITSclus,   int maxITSclus, 
85                       int minTrackMult, int maxTrackMult,
86                       int vs,           float vz
87                       //float minCent,    float maxCent
88                     );
89 void plotTrackQuantities( THnSparse* htrackHLT, THnSparse* htrackOFF, 
90                           TText* hText,         TString folder,
91                           double minEta,        double maxEta,
92                           double minPt,         double maxPt,
93                           double minDCAr,       double maxDCAr,
94                           double minDCAz,       double maxDCAz,
95                           int minTPCclus,       int maxTPCclus,
96                           int minITSclus,       int maxITSclus, 
97                           int minTrackMult,     int maxTrackMult,
98                           int vs,               float vz,
99                           float minCent,        float maxCent
100                         );
101                         
102 vector<TString> outputNames;
103
104 //------------------------------------------------------------------//          
105
106 void drawTHnSparse(TString inputFile="HLT-OFFLINE-CentralBarrel-comparison.root"){
107  
108   gROOT->SetStyle("Plain");
109   gStyle->SetPalette(1);
110   gStyle->SetOptStat("emr");
111   gStyle->SetTitleX(gStyle->GetPadLeftMargin());
112   TH1::AddDirectory(kFALSE);
113
114   TFile *file = TFile::Open(inputFile);
115   if(!file){
116     printf("Error: No file %s in folder.\n", inputFile.Data());
117     return;
118   }
119   TList *list = static_cast<TList*>(file->Get("esd_thnsparse"));
120   if(!list){
121     printf("Error: No List contained in file %s.\n", inputFile.Data());
122     return;
123   }
124   THnSparseF *heventHLT = (THnSparseF*)list->FindObject("fEventHLT"); 
125   if(!heventHLT){
126       printf("Error: There is no HLT THnSparse object in file %s\n", inputFile.Data());
127       return;
128   }
129   THnSparseF *heventOFF = (THnSparseF*)list->FindObject("fEventOFF");  
130   if(!heventOFF){
131       printf("Error: There is no OFF THnSparse object in file %s\n", inputFile.Data());
132       return;
133   } 
134   THnSparseF *htrackHLT = (THnSparseF*)list->FindObject("fTrackHLT");
135   if(!htrackHLT){
136       printf("Error: No HLT THnSparse object found\n");
137       return;
138   } 
139   THnSparseF *htrackOFF = (THnSparseF*)list->FindObject("fTrackOFF");  
140   if(!htrackOFF){
141       printf("Error: No OFF THnSparse object found\n");
142       return;
143   }
144       
145   TText *hText = (TText*)list->FindObject("text");
146   if(!hText) printf("No hText\n");
147    
148   TString folder = hText->GetTitle();
149   folder.ReplaceAll(" ",""); 
150   folder.ReplaceAll(",","_");    
151   gSystem->Exec("mkdir "+folder); // create a folder whose name contains run number and date of run
152   
153   if(heventHLT->GetEntries()>0 || heventOFF->GetEntries()>0) plotEventQuantities(heventHLT,heventOFF,hText,folder);
154   else {
155     if(heventHLT->GetEntries()==0) printf("\nThe HLT event THnSparse contains 0 entries\n");
156     if(heventOFF->GetEntries()==0) printf("\nThe OFF event THnSparse contains 0 entries\n");
157   }
158
159   int counter = 0; 
160   // counts how many times the function cutStudies() is called
161   // if more than once, then it creates and fills the canvas with the overlapping hlt distributions for the various sets of cuts
162   
163   TString s = "";                                     // eta   mult      pt      DCAr     DCAz   TPCclus  ITSclus  vertexStatus  |vertexZ|    
164   s = cutStudies(folder, htrackHLT, htrackOFF, hText, -2, 2, 0, 2000, 0,    10, -10, 10, -10, 10,  0, 200,  0, 6,      2,       10, 0, 100); outputNames.push_back(s); counter++;     
165   /*
166   s = cutStudies(folder, htrackHLT, htrackOFF, hText, -1, 1, 0, 2000, 0,    10, -10, 10, -10, 10,  0, 200,  0, 6,      2,       10, 0, 100); outputNames.push_back(s); counter++;
167   s = cutStudies(folder, htrackHLT, htrackOFF, hText, -1, 1, 0, 2000, 0,    10,  -7,  7, -10, 10,  0, 200,  0, 6,      2,       10, 0, 100); outputNames.push_back(s); counter++;
168   s = cutStudies(folder, htrackHLT, htrackOFF, hText, -1, 1, 0, 2000, 0,    10,  -7,  7,  -7,  7,  0, 200,  0, 6,      2,       10, 0, 100); outputNames.push_back(s); counter++;
169   s = cutStudies(folder, htrackHLT, htrackOFF, hText, -1, 1, 0, 2000, 0.25, 10,  -7,  7,  -7,  7,  0, 200,  0, 6,      2,       10, 0, 100); outputNames.push_back(s); counter++;
170   s = cutStudies(folder, htrackHLT, htrackOFF, hText, -1, 1, 0, 2000, 0.25, 10,  -3,  3,  -3,  3,  0, 200,  0, 6,      2,       10, 0, 100); outputNames.push_back(s); counter++;
171   */
172   
173   if(counter>=2){          
174      TString tmp = "overlaid HLT track distributions for ";
175      tmp += hText->GetTitle();
176      TCanvas *ovHLT = new TCanvas("ovHLT",tmp,1100,900);
177      ovHLT->Divide(3,3);
178      
179      tmp = "overlaid OFF track distributions for ";
180      tmp += hText->GetTitle();
181      TCanvas *ovOFF = new TCanvas("ovOFF",tmp,1100,900);
182      ovOFF->Divide(3,3);
183
184      TCanvas *ca; TFile *ff; TPad *pad; 
185      TH1D *hlt[outputNames.size()];
186      TH1D *off[outputNames.size()];
187  
188      for(int j=1; j<10; j++){ // loop over the pads of the canvas "ov" with dimension 3x3     
189        for(UInt_t i=0; i<outputNames.size(); i++){ // loop over the files with different sets of cuts
190               
191            ff = TFile::Open(outputNames[i].Data());   
192            if(!ff || ff->IsZombie()){
193               printf("Non-existent, corrupted or zombie file %s\n", outputNames[i].Data());
194               return;
195            } 
196            ca  = (TCanvas*)ff->GetObjectUnchecked("can3");             
197            if(!ca){
198               printf("Empty canvas in file %s.\n", outputNames[i].Data());
199               continue;
200            }       
201            pad = (TPad*)ca->GetListOfPrimitives()->FindObject(Form("can3_%d",j));          
202            if(!pad){
203               printf("Empty pad in canvas %s.\n", ca->GetName());
204               continue;         
205            }
206            hlt[i] =(TH1D*)pad->FindObject(Form("fTrackHLT_proj_%d",j-1));
207            off[i] =(TH1D*)pad->FindObject(Form("fTrackOFF_proj_%d",j-1));
208            if(!hlt[i] || !off[i]){
209               printf("Empty histogram for i=%d, file %s.\n", i, outputNames[i].Data());
210               continue;
211            }
212            ovHLT->cd(j);           
213            if(i==0){
214               TPaveStats *st = (TPaveStats*)hlt[i]->FindObject("stats"); 
215               st->SetTextColor(kBlack);
216               hlt[i]->Draw();
217            }
218            else { 
219              hlt[i]->SetLineColor(i+1); 
220              defineYaxisMax(hlt[0], hlt[i]); 
221              hlt[i]->Draw("sames");
222            }
223            if(i>0) printStats(hlt[i-1], hlt[i]);
224           
225            ovOFF->cd(j);           
226            if(i==0){
227               off[i]->SetLineColor(kBlack); 
228               TPaveStats *st = (TPaveStats*)off[i]->FindObject("stats"); 
229               st->SetTextColor(kBlack);
230               off[i]->Draw();
231            }
232            else { 
233              off[i]->SetLineColor(i+1); 
234              defineYaxisMax(off[0], off[i]); 
235              off[i]->Draw("sames");
236            }
237            if(i>0) printStats(off[i-1], off[i]);
238            
239            ff->Close();                                     
240        } // end of loop over files 
241      } // end of loop over canvas pads
242      file->Close();  
243      ovHLT->SaveAs(folder+"/overlaid_HLT_track_cuts.root");
244      ovHLT->SaveAs(folder+"/overlaid_HLT_track_cuts.png");  
245      ovOFF->SaveAs(folder+"/overlaid_OFF_track_cuts.root");
246      ovOFF->SaveAs(folder+"/overlaid_OFF_track_cuts.png");  
247      delete ovHLT;
248      delete ovOFF;
249   } // end if for counter>=2
250   return;
251 }
252
253 // ============== main function for filling the track properties, 1D and 2D ================ //
254
255 TString cutStudies( TString folder,
256                     THnSparse* htrackHLT, THnSparse* htrackOFF, TText* hText,
257                     double minEta,   double maxEta,
258                     int minTrackMult,int maxTrackMult,
259                     double minPt,    double maxPt,
260                     double minDCAr,  double maxDCAr,
261                     double minDCAz,  double maxDCAz,
262                     int minTPCclus,  int maxTPCclus,
263                     int minITSclus,  int maxITSclus,
264                     int vs,          float vz,
265                     float minCent,   float maxCent
266                   ){
267
268   plotTrackQuantities(htrackHLT, htrackOFF, hText, folder,
269                       minEta, maxEta, minPt, maxPt, minDCAr, maxDCAr, minDCAz, maxDCAz, minTPCclus, maxTPCclus, minITSclus, maxITSclus, 
270                       minTrackMult, maxTrackMult, vs, vz, minCent, maxCent);
271
272   if(htrackHLT->GetEntries()>0) plot2D(htrackHLT, hText, folder, minEta, maxEta, minPt, maxPt, minDCAr, maxDCAr, minDCAz, maxDCAz, minTPCclus, maxTPCclus, minITSclus, maxITSclus, 
273          minTrackMult, maxTrackMult, vs, vz, minCent, maxCent);  
274
275   if(htrackOFF->GetEntries()>0) plot2D(htrackOFF, hText, folder, minEta, maxEta, minPt, maxPt, minDCAr, maxDCAr, minDCAz, maxDCAz, minTPCclus, maxTPCclus, minITSclus, maxITSclus, 
276          minTrackMult, maxTrackMult, vs, vz, minCent, maxCent);
277
278   TString cuts = cutsToString(minEta, maxEta, minPt, maxPt, minDCAr, maxDCAr, minDCAz, maxDCAz, minTPCclus, maxTPCclus, 
279                               minITSclus, maxITSclus, minTrackMult, maxTrackMult, vs, vz);
280   
281   return folder+"/track_properties_"+cuts+".root"; // same name as the one produced by plotTrackQuantities internally
282 }
283
284 void plotEventQuantities(THnSparse* heventHLT, THnSparse* heventOFF, TText* hText, TString folder){
285
286   TString tmp = "vertex event properties for ";
287   tmp += hText->GetTitle();
288   TCanvas *can1 = new TCanvas("can1",tmp,1200,700);
289   can1->Divide(3,2); 
290   
291   heventHLT->GetAxis(8)->SetRangeUser(1,1); // select events with existing primary vertex       
292   heventOFF->GetAxis(8)->SetRangeUser(1,1);
293   TH1D *hlt = NULL; 
294   TH1D *off = NULL;
295   
296   for(int i=0; i<6; i++){ // loop for HLT/OFF primary and SPD vertex xyz
297       can1->cd(i+1);
298       hlt = heventHLT->Projection(i); if(!hlt){ printf("plotEventQuantities: empty HLT histogram, projection %d\n",i); continue; }
299       off = heventOFF->Projection(i); if(!off){ printf("plotEventQuantities: empty OFF histogram, projection %d\n",i); continue; }
300       off->SetLineColor(2); 
301       hlt->SetTitle(fix1DTitle(heventHLT->Projection(i)->GetTitle())); 
302       off->SetTitle(fix1DTitle(heventOFF->Projection(i)->GetTitle()));       
303       TString s = hlt->GetTitle();      
304       if(s.Contains("primary")){ 
305          s+=" (cm)";
306          hlt->SetXTitle(s); 
307          off->SetXTitle(s);    
308       }
309       if(off->GetEntries()>0) defineYaxisMax(hlt, off);
310       
311       if(hlt->GetEntries()>0) hlt->Draw();
312       if(off->GetEntries()>0) off->Draw("sames");
313       if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off);
314       if(off->GetEntries()>0 && i==0 ) printLegend(hlt,off);
315   }
316   
317   tmp = "general event properties for ";
318   tmp += hText->GetTitle(); 
319   TCanvas *can2 = new TCanvas("can2",tmp,1200,700);
320   can2->Divide(3,2);
321   
322   can2->cd(1); // track multiplicity
323   hlt = heventHLT->Projection(7); 
324   off = heventOFF->Projection(7); 
325   off->SetLineColor(2); 
326   hlt->SetTitle(fix1DTitle(heventHLT->Projection(7)->GetTitle())); 
327   off->SetTitle(fix1DTitle(heventOFF->Projection(7)->GetTitle()));       
328   if(off->GetEntries()>0) defineYaxisMax(hlt, off);
329   if(hlt->GetEntries()>0) hlt->Draw();
330   if(off->GetEntries()>0){ off->Draw("sames"); printLegend(hlt,off); }
331   if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off);
332
333   can2->cd(2); // number of contributors
334   hlt = heventHLT->Projection(6); 
335   off = heventOFF->Projection(6); 
336   off->SetLineColor(2); 
337   hlt->SetTitle(fix1DTitle(heventHLT->Projection(6)->GetTitle())); 
338   off->SetTitle(fix1DTitle(heventOFF->Projection(6)->GetTitle()));       
339   if(off->GetEntries()>0) defineYaxisMax(hlt, off);
340   if(hlt->GetEntries()>0) hlt->Draw();
341   if(off->GetEntries()>0) off->Draw("sames");
342   if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off);
343    
344   can2->cd(3); // vertex status
345   hlt = heventHLT->Projection(8); 
346   off = heventOFF->Projection(8); 
347   off->SetLineColor(2); 
348   hlt->SetTitle(fix1DTitle(heventHLT->Projection(8)->GetTitle())); 
349   off->SetTitle(fix1DTitle(heventOFF->Projection(8)->GetTitle()));       
350   if(off->GetEntries()>0) defineYaxisMax(hlt, off);
351   if(hlt->GetEntries()>0) hlt->Draw();
352   if(off->GetEntries()>0) off->Draw("sames");
353   if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off); 
354   
355   can2->cd(4); // # of contributors vs. track multiplicity for HLT
356   TH2D *h = heventHLT->Projection(6,7);
357   TString s1 = fix2DTitle(heventHLT->Projection(6)->GetTitle(), heventHLT->Projection(7)->GetTitle()); s1+=" (HLT)";
358   h->SetTitle(s1);
359   h->Draw("colz");
360   
361   can2->cd(5); // # of contributors vs. track multiplicity for OFF
362   TH2D *o = heventOFF->Projection(6,7);
363   s1 = fix2DTitle(heventOFF->Projection(6)->GetTitle(), heventOFF->Projection(7)->GetTitle()); s1+=" (OFF)";
364   o->SetTitle(s1);
365   o->Draw("colz");
366    
367   if(heventHLT->GetNdimensions()==10){
368      can2->cd(6);
369      off = heventOFF->Projection(9); // V0 centrality, taken from the offline ESD
370      off->SetTitle(fix1DTitle(heventOFF->Projection(9)->GetTitle()));
371      off->SetLineColor(2);
372      off->Draw();
373   }  
374   
375   can1->SaveAs(folder+"/vertex_event_properties.root");
376   can1->SaveAs(folder+"/vertex_event_properties.png");
377   can2->SaveAs(folder+"/general_event_properties.root");
378   can2->SaveAs(folder+"/general_event_properties.png");
379   delete can1;
380   delete can2;
381   return;
382 }
383
384 void plotTrackQuantities( THnSparse* htrackHLT, THnSparse* htrackOFF, 
385                           TText* hText,         TString folder,
386                           double minEta,        double maxEta,
387                           double minPt,         double maxPt,
388                           double minDCAr,       double maxDCAr,
389                           double minDCAz,       double maxDCAz,
390                           int minTPCclus,       int maxTPCclus,
391                           int minITSclus,       int maxITSclus, 
392                           int minTrackMult,     int maxTrackMult,
393                           int vs,               float vz,
394                           float minCent,        float maxCent
395                         )
396 {
397    
398   htrackHLT->GetAxis(0)->SetRangeUser(minPt,maxPt);
399   htrackHLT->GetAxis(1)->SetRangeUser(minTPCclus,maxTPCclus);
400   htrackHLT->GetAxis(3)->SetRangeUser(minEta, maxEta);
401   htrackHLT->GetAxis(5)->SetRangeUser(minDCAr, maxDCAr);
402   htrackHLT->GetAxis(6)->SetRangeUser(minDCAz, maxDCAz);
403   htrackHLT->GetAxis(8)->SetRangeUser(minITSclus, maxITSclus);
404   htrackHLT->GetAxis(9)->SetRangeUser(minTrackMult, maxTrackMult);
405   if(vs!=2) htrackHLT->GetAxis(10)->SetRangeUser(vs,vs);
406   htrackHLT->GetAxis(11)->SetRangeUser(-TMath::Abs(vz), TMath::Abs(vz));
407   if(htrackHLT->GetNdimensions()==13) htrackHLT->GetAxis(12)->SetRangeUser(minCent, maxCent);
408   
409   htrackOFF->GetAxis(0)->SetRangeUser(minPt,maxPt);
410   htrackOFF->GetAxis(1)->SetRangeUser(minTPCclus,maxTPCclus);
411   htrackOFF->GetAxis(3)->SetRangeUser(minEta, maxEta);
412   htrackOFF->GetAxis(5)->SetRangeUser(minDCAr, maxDCAr);
413   htrackOFF->GetAxis(6)->SetRangeUser(minDCAz, maxDCAz);
414   htrackOFF->GetAxis(8)->SetRangeUser(minITSclus, maxITSclus);
415   htrackOFF->GetAxis(9)->SetRangeUser(minTrackMult, maxTrackMult);
416   if(vs!=2) htrackOFF->GetAxis(10)->SetRangeUser(vs,vs);
417   htrackOFF->GetAxis(11)->SetRangeUser(-TMath::Abs(vz), TMath::Abs(vz));
418   if(htrackOFF->GetNdimensions()==13) htrackOFF->GetAxis(12)->SetRangeUser(minCent, maxCent);
419   
420   TString tmp = "";
421   tmp += "track properties for ";
422   tmp+=hText->GetTitle();     
423   TCanvas *can3 = new TCanvas("can3",tmp,1100,900); 
424   can3->Divide(3,3); 
425   // the first 9 track related variables filled in the THnSparse
426   //  0     1     2    3   4      5      6     7       8  
427   // pt  TPCcl theta eta   phi   DCAr  DCAz charge  ITScl 
428   
429   TH1D *hlt = NULL; 
430   TH1D *off = NULL;
431       
432   for(int i=0; i<9; i++){  
433      hlt = htrackHLT->Projection(i); if(!hlt){ printf("plotTrackQuantities: empty HLT histogram for projection %d\n",i); continue; }
434      off = htrackOFF->Projection(i); if(!off){ printf("plotTrackQuantities: empty OFF histogram for projection %d\n",i); continue; }     
435      hlt->SetTitle(fix1DTitle(htrackHLT->Projection(i)->GetTitle())); 
436      off->SetTitle(fix1DTitle(htrackOFF->Projection(i)->GetTitle())); // is necessary in cases where only offline data is available
437   
438      TString s = hlt->GetTitle();      
439      if(s.Contains("p_")){ 
440         s+=" (GeV/c)";
441         hlt->SetXTitle(s);     
442      }
443      else if(s.Contains("theta") || s.Contains("phi")){
444         s+=" (rad)"; 
445         hlt->SetXTitle(s);
446      }
447      else if(s.Contains("DCA")){
448         s+=" (cm)";
449         hlt->SetXTitle(s);
450      }
451        
452      if(off->GetEntries()>0) defineYaxisMax(hlt, off);
453      off->SetLineColor(2);
454    
455      can3->cd(i+1);
456      if(hlt->GetEntries()>0) hlt->Draw();
457      if(off->GetEntries()>0) off->Draw("sames");
458      if(hlt->GetEntries()>0 && off->GetEntries()>0) printStats(hlt, off);
459      if(off->GetEntries()>0 && i==0 ) printLegend(hlt,off);
460      
461      if(hlt->GetEntries()>0 && i==0){
462         TPaveText *pave = new TPaveText(25,5600,140,36400);
463         pave->SetFillColor(kWhite);
464         pave->SetLineColor(kWhite);
465         pave->SetShadowColor(kWhite);
466         s=""; s+=minEta; s+=" < eta < "; s+=maxEta; pave->AddText(s);
467         s=""; s+=minPt; s+=" < pt (GeV/c) < "; s+=maxPt; pave->AddText(s);
468         s=""; s+=minTrackMult; s+=" < track mult < "; s+=maxTrackMult; pave->AddText(s);
469         s=""; s+=minDCAr; s+=" < DCAr (cm) < "; s+=maxDCAr; pave->AddText(s);
470         s=""; s+=minDCAz; s+=" < DCAz (cm) < "; s+=maxDCAz; pave->AddText(s);
471         s=""; s+=minTPCclus; s+=" < TPC clusters/track < "; s+=maxTPCclus; pave->AddText(s);
472         s=""; s+=minITSclus; s+=" < ITS clusters/track < "; s+=maxITSclus; pave->AddText(s);
473         if(vs!=2) { s=""; s+="vertex status "; s+=vs; pave->AddText(s); }
474         pave->Draw();
475         can3->Update();
476      }      
477   } 
478   TString cuts = cutsToString(minEta, maxEta, minPt, maxPt, minDCAr, maxDCAr, minDCAz, maxDCAz, minTPCclus, maxTPCclus, 
479                               minITSclus, maxITSclus, minTrackMult, maxTrackMult, vs, vz);
480   
481   can3->SaveAs(folder+"/track_properties_"+cuts+".root");
482   can3->SaveAs(folder+"/track_properties_"+cuts+".png");
483   delete can3;
484   
485   return;
486 }
487
488 //====================== for 2D track distributions ===============================//
489
490 void plot2D( THnSparse* h,     TText *hText, TString folder,
491              double minEta,    double maxEta,
492              double minPt,     double maxPt,
493              double minDCAr,   double maxDCAr,
494              double minDCAz,   double maxDCAz,
495              int minTPCclus,   int maxTPCclus,
496              int minITSclus,   int maxITSclus, 
497              int minTrackMult, int maxTrackMult,
498              int vs,           float vz,
499              float minCent,    float maxCent
500            )
501 {
502   h->GetAxis(0)->SetRangeUser(minPt,maxPt);
503   h->GetAxis(1)->SetRangeUser(minTPCclus,maxTPCclus);
504   h->GetAxis(3)->SetRangeUser(minEta, maxEta);
505   h->GetAxis(5)->SetRangeUser(minDCAr, maxDCAr);
506   h->GetAxis(6)->SetRangeUser(minDCAz, maxDCAz);
507   h->GetAxis(8)->SetRangeUser(minITSclus, maxITSclus);
508   h->GetAxis(9)->SetRangeUser(minTrackMult, maxTrackMult);
509   if(vs!=2) h->GetAxis(10)->SetRangeUser(vs,vs);
510   h->GetAxis(11)->SetRangeUser(-TMath::Abs(vz), TMath::Abs(vz));
511   if(h->GetNdimensions()==13) h->GetAxis(12)->SetRangeUser(minCent, maxCent);
512   
513   TString name = h->GetName();
514   TString tmp = "";
515   if(name.Contains("HLT")) tmp = "HLT 2-D track distributions for ";
516   else tmp = "OFF 2-D track distributions for ";
517
518   tmp += hText->GetTitle();
519   TCanvas *can4 = new TCanvas("can4",tmp,1200,800);
520   can4->Divide(4,2);
521
522   can4->cd(1);    
523   TH2D *ht = h->Projection(1,0); // TPC clusters/track vs. pt
524   ht->SetTitle(fix2DTitle(h->Projection(1)->GetTitle(), h->Projection(0)->GetTitle()));
525
526   TString s = "";
527   s = fix1DTitle(h->Projection(0)->GetTitle())+" (GeV/c)";
528   ht->SetXTitle(s);
529   ht->Draw("colz");
530   
531   can4->cd(2);
532   ht = h->Projection(1,3); // TPC clusters/track vs. eta
533   ht->SetTitle(fix2DTitle(h->Projection(1)->GetTitle(), h->Projection(3)->GetTitle()));
534   ht->Draw("colz");
535   
536   can4->cd(3);
537   ht = h->Projection(1,5); // TPC clusters/track vs. DCAr
538   ht->SetTitle(fix2DTitle(h->Projection(1)->GetTitle(), h->Projection(5)->GetTitle()));
539   s = fix1DTitle(h->Projection(5)->GetTitle())+" (cm)";
540   ht->SetXTitle(s);
541   ht->Draw("colz");
542   
543   can4->cd(4);
544   ht = h->Projection(1,6); // TPC clusters/track vs. DCAz
545   ht->SetTitle(fix2DTitle(h->Projection(1)->GetTitle(), h->Projection(6)->GetTitle()));
546   s = fix1DTitle(h->Projection(6)->GetTitle())+" (cm)";
547   ht->SetXTitle(s);
548   ht->Draw("colz");
549   
550   can4->cd(5);
551   ht = h->Projection(5,0); // DCAr vs. pt
552   ht->SetTitle(fix2DTitle(h->Projection(5)->GetTitle(), h->Projection(0)->GetTitle()));
553   s = fix1DTitle(h->Projection(0)->GetTitle())+" (GeV/c)";
554   ht->SetXTitle(s);
555   s = fix1DTitle(h->Projection(5)->GetTitle())+" (cm)";
556   ht->SetYTitle(s);
557   ht->Draw("colz");
558   
559   can4->cd(6);
560   ht = h->Projection(6,3); // DCAz vs. pt
561   ht->SetTitle(fix2DTitle(h->Projection(6)->GetTitle(), h->Projection(3)->GetTitle()));
562   s = fix1DTitle(h->Projection(6)->GetTitle())+" (cm)";
563   ht->SetYTitle(s);
564   ht->Draw("colz");
565   
566   can4->cd(7);
567   ht = h->Projection(3,0); // eta vs. pt
568   ht->SetTitle(fix2DTitle(h->Projection(3)->GetTitle(), h->Projection(0)->GetTitle()));
569   s = fix1DTitle(h->Projection(0)->GetTitle())+" (GeV/c)";
570   ht->SetXTitle(s);
571   ht->Draw("colz");
572   
573   can4->cd(8);
574   ht = h->Projection(3,4); // eta vs. phi
575   ht->SetTitle(fix2DTitle(h->Projection(3)->GetTitle(), h->Projection(4)->GetTitle()));
576   s = fix1DTitle(h->Projection(4)->GetTitle())+" (rad)";
577   ht->SetXTitle(s);
578   ht->Draw("colz");
579  
580   TString cuts = cutsToString(minEta, maxEta, minPt, maxPt, minDCAr, maxDCAr, minDCAz, maxDCAz, minTPCclus, maxTPCclus, 
581                               minITSclus, maxITSclus, minTrackMult, maxTrackMult, vs, vz);
582   if(name.Contains("HLT")){
583      can4->SaveAs(folder+"/HLT_2D_track_correlations_"+cuts+".root"); 
584      can4->SaveAs(folder+"/HLT_2D_track_correlations_"+cuts+".png"); 
585   } else {
586      can4->SaveAs(folder+"/OFF_2D_track_correlations_"+cuts+".root"); 
587      can4->SaveAs(folder+"/OFF_2D_track_correlations_"+cuts+".png"); 
588   }
589   delete can4;
590   return;
591 }
592
593 TString cutsToString( double minEta,    double maxEta,
594                       double minPt,     double maxPt,
595                       double minDCAr,   double maxDCAr,
596                       double minDCAz,   double maxDCAz,
597                       int minTPCclus,   int maxTPCclus,
598                       int minITSclus,   int maxITSclus, 
599                       int minTrackMult, int maxTrackMult,
600                       int vs,           float vz
601 //                    float minCent,    float maxCent
602                     )
603 {
604   TString cuts = "";
605   char s[300]; sprintf(s, "eta%2g_%2g_Pt%2g_%2g_TM%d_%d_DCAr%2g_%2g_DCAz%2g_%2g_TPCclus%d_%d_ITSclus%d_%d_Zvertex%2g", 
606                            minEta,maxEta,minPt,maxPt,minTrackMult,maxTrackMult,minDCAr,maxDCAr,minDCAz,maxDCAz,minTPCclus,maxTPCclus,minITSclus,maxITSclus,vz);
607   cuts = s; cuts.ReplaceAll(" ","");
608  
609   if(vs!=2){
610     char v[10]; 
611     sprintf(v, "_VS%d",vs);
612     cuts+=v;
613   }
614   return cuts;
615 }
616
617 void printStats(TH1D *hlt, TH1D *off){  
618   gPad->Update();
619   TPaveStats *st1 = (TPaveStats*)hlt->FindObject("stats");
620   st1->SetLineColor(0);
621   st1->SetTextSize(7);
622   st1->SetTextFont(8);
623
624   gPad->Update();
625   TPaveStats *st2 = (TPaveStats*)off->FindObject("stats");
626   st2->SetY2NDC(st1->GetY1NDC()-0.05);
627   st2->SetY1NDC(st2->GetY2NDC()-TMath::Abs(st1->GetY1NDC()-st1->GetY2NDC()));
628   st2->SetLineColor(0);
629   st2->SetTextColor(off->GetLineColor());
630   st2->SetFillStyle(0);
631   st2->SetTextSize(7);
632   st2->SetTextFont(8);
633   st2->Draw();
634   return;
635 }
636
637 void defineYaxisMax(TH1D *h1, TH1D *h2){ 
638   //Y axis
639   if(h1->GetMaximum() > h2->GetMaximum()) h2->SetMaximum(1.1*h1->GetMaximum());
640   else h1->SetMaximum(1.1*h2->GetMaximum());
641   
642   h1->SetMinimum(0);
643   h2->SetMinimum(0);
644  
645   // X axis  
646   double xmin, xmax;  
647   if(h1->GetBinLowEdge(1) > h2->GetBinLowEdge(1)) xmin = h1->GetBinLowEdge(1);
648   else xmin = h2->GetBinLowEdge(1);
649   if(h1->GetBinLowEdge(h1->GetNbinsX()+1) > h2->GetBinLowEdge(h1->GetNbinsX()+1)) xmax = h1->GetBinLowEdge(h1->GetNbinsX()+1);
650   else xmax = h2->GetBinLowEdge(h2->GetNbinsX()+1);
651   
652   h2->SetAxisRange(xmin, xmax, "X");  
653   return;
654 }
655
656 void printLegend(TH1D *hlt, TH1D *off){  
657   TLegend *l = new TLegend(0.5,0.5,0.7,0.7);
658   l->SetFillColor(10); 
659   l->SetLineColor(10);
660   l->AddEntry(hlt, "HLT", "l");
661   l->AddEntry(off, "OFF", "l");
662   l->Draw("same");
663   return;
664 }
665
666 TString fix1DTitle(const char* c){
667   TString tmp = c;
668   tmp.ReplaceAll("projection ","");
669   return tmp;   
670 }
671
672 TString fix2DTitle(const char* c1, const char* c2){
673   TString tmp = fix1DTitle(c1)+" vs."+fix1DTitle(c2);
674   return tmp;
675 }