end-of-line normalization
[u/mrichter/AliRoot.git] / ANALYSIS / macros / PhysSelQA / AliPSQAVisualization.cxx
1 /////////////////////////////////////
2 // Created by: Kevin McDermott     //
3 // email: kmcderm3@nd.edu          //
4 // CERN Summer Student 2012        //
5 // University of Notre Dame du Lac //
6 //                                 // 
7 // Revision: 1.0                   //
8 // Created on: August 6, 2012      //
9 /////////////////////////////////////
10
11 #include "AliPSQAVisualization.h"
12
13 ClassImp(AliPSQAVisualization)
14
15 AliPSQAVisualization::AliPSQAVisualization(): // Default constructor
16 TObject(),
17 fRunNumbers(0),
18 fFillNumbers(0),
19 fRawRunNumbers(0),
20 fRawFillNumbers(0),
21 fNRuns(0),
22 fNRawRuns(0),
23 fFillSeparationLine(0x0)
24 {
25   // Initialize some private data members from AliPSQAV
26   fInDirectory = "";
27   fROOTInput = "";
28   fRunFillFile = "";
29   fSavePDFs = kFALSE;
30   fOutDirectory = "";
31   fOutPDFName = "";
32   fOutEPSName = "";
33   fDrawOverPlot = kFALSE;
34   fOverPlotTitle = "";
35   fMaximum = -1000;
36   fMinimum =  1000;
37   fScaleAuto = kFALSE;
38   fUseColorArray = kFALSE;
39   fMultMax = 0;
40   fDivMin = 0;
41   InitializeColorArray("");
42   InitializeSelectedPlots("");
43 }
44
45 //________________________________________________________________________________________________
46 AliPSQAVisualization::~AliPSQAVisualization(){
47   delete[] fCanvas;
48   delete[] fDrawPlot;
49   delete[] fFillSeparationLine;
50   delete[] fSelectedPlots;
51   delete[] fColors;
52   delete fOverLegend;
53 }
54
55 //________________________________________________________________________________________________
56 void AliPSQAVisualization::InitializeColorArray(const Char_t * listOfColors){ // Function to custom set color array used for plots, not essential
57   Color_t colors; //color enums from list
58   ifstream input_data_col; //text file object
59   input_data_col.open(listOfColors, ios::in );  //open the text file
60   Int_t Ncol = 0; //number of color names to be used
61
62   while ( input_data_col >> colors ) { // count number of color names
63     Ncol++;
64   }
65
66   fNColors = Ncol; // Set private data member to total color names to be used
67   input_data_col.close(); // reset the file
68
69   fColors = new Color_t [fNColors]; // initialize private data member with number of trig names
70   input_data_col.open(listOfColors, ios::in );
71   for (Int_t icol = 0; icol < fNColors; icol++){
72     input_data_col >> fColors[icol];
73   }
74
75   input_data_col.close();
76 }
77
78 //________________________________________________________________________________________________
79 void AliPSQAVisualization::InitializeSelectedPlots(const Char_t * listOfPlots){
80   TString plotnames; //plot names from list
81   ifstream input_data_pn; //text file object
82   if(!listOfPlots) cout << "No list of plots" << endl;
83   input_data_pn.open(listOfPlots, ios::in );  //open the text file
84   Int_t Npn = 0; //number of plot names to be used
85
86   while ( input_data_pn >> plotnames ) { // count number of plot names
87     Npn++;
88   }
89
90   cout << "Number of initalized plots = " << Npn << endl;
91
92   fNSelectedPlots = Npn; // Set private data member to total plot names to be used
93   input_data_pn.close(); // reset the file
94   //cout << "Number of selected plots = " << fNSelectedPlots << endl;
95   fSelectedPlots = new TString [fNSelectedPlots]; // initialize private data member with number of trig names
96   input_data_pn.open(listOfPlots, ios::in );
97   for (Int_t iplot = 0; iplot < fNSelectedPlots; iplot++){
98     input_data_pn >> fSelectedPlots[iplot];
99     //cout << "Plots to process :" << fSelectedPlots[iplot] << endl;
100   }
101
102   input_data_pn.close();
103 }
104
105 //________________________________________________________________________________________________
106 void AliPSQAVisualization::PostProcessQA(){
107
108   if(!fROOTInput) cout << "No .root file found" << endl;
109
110   //cout << "Sto morendo qua? 1" << endl;
111   gStyle->SetOptStat(0);
112   gStyle->SetPalette(1);
113   gStyle->SetFillColor(10);
114   gStyle->SetOptStat(0);
115   gStyle->SetOptTitle(1);
116   // do not use scientific notation for run number
117   TGaxis::SetMaxDigits(6);
118   //cout << "Sto morendo qua? 2" << endl;
119   ConvertTGraphErrorsToTH1Ds();  // Convert all plots to TH1D's from specified plot list
120   //cout << "Sto morendo qua? 3" << endl;
121   fCanvas = new TCanvas[fNSelectedPlots]; // Allocate memory for the canvases to draw PostProcessing
122    
123   if ((fDrawOverPlot) || (fSaveOverPlotPDF) || (fSaveOverPlotEPS)){
124     fOverLegend = new TLegend(0.55,0.625,.75,.85);
125     if (fScaleAuto){
126       ScaleMinAndMax();
127     }
128   }
129
130   if ((fSavePDFs) || (fSaveOverPlotPDF) || (fSaveOverPlotEPS)){
131     FileStat_t dummy_filestat;
132     if (gSystem->GetPathInfo(fOutDirectory.Data(), dummy_filestat) == 1) { // cache directory does not exist
133       MakeDir(fOutDirectory);
134     }
135   }
136
137   // *************************************** LOOP ON PLOTS ***************************************
138
139   for (Int_t iplot = 0; iplot < fNSelectedPlots; iplot++){ // Loop over the number of plots to be made pretty and drawn
140     DrawSelected(iplot); // Draw the Selected plots, decide later whether to have them open/save them
141   
142     DrawSameTriggerOnSameCA(iplot);
143     cout << "Draw selected - OK " << endl;
144
145     if (fSavePDFs){ // Write the canvas to the PDF file if kTRUE
146       SavePDFs(iplot);
147       SaveToPDFSeparately(iplot);
148     }
149
150     if (!fDrawSelected){ // Close the canvas if you do not want to see the plot
151       fCanvas[iplot].Close();
152     }
153
154     if ( (fDrawOverPlot) || (fSaveOverPlotPDF) || (fSaveOverPlotEPS) ) { // Set points and draw overplot if any are true
155       if (fUseColorArray){
156         DrawOverPlotCA(iplot);
157       }
158       else{
159         DrawOverPlotNoCA(iplot);
160       }
161     }
162     else if( (!fDrawOverPlot) && ( (fSaveOverPlotPDF) || (fSaveOverPlotEPS) ) ) { // Set the points to save to and/or pdf/eps but then close it outside the loop
163       if (fUseColorArray){
164         DrawOverPlotCA(iplot);
165       }
166       else{
167         DrawOverPlotNoCA(iplot);
168       }
169     }
170
171   } // end loop on plots
172
173   if (fSaveOverPlotPDF){ // Save the overplot to pdf
174     SaveOverPlotPDF();
175   }
176   if (fSaveOverPlotEPS){ // Save the overplot to eps
177     SaveOverPlotEPS();
178   }
179   if (!fDrawOverPlot){ // Close if you do not want to see it
180     fOverCanvas.Close();
181   }
182 }
183
184 //________________________________________________________________________________________________
185 Int_t AliPSQAVisualization::MatchGoodRunToFillNumber(Int_t runnumber){
186
187   Int_t fill = -1;
188
189   for(Int_t irun = 0; irun < fNRawRuns; irun++){
190     if(runnumber == fRawRunNumbers[irun]){
191       fill = fRawFillNumbers[irun];
192       // cout << runnumber << " matched to fill " << fill << endl;
193     }
194   }
195   //   cout << "Matching completed" << endl;
196   return fill;
197 }
198
199 //________________________________________________________________________________________________
200 Int_t AliPSQAVisualization::MatchGoodRunToStats(Int_t runnumber){
201
202   Int_t Stats = -1;
203
204   for(Int_t irun = 0; irun < fNRawRuns; irun++){
205     if(runnumber == fRawRunNumbers[irun]){
206       Stats = fRawRunStats[irun];
207       // cout << runnumber << " matched to fill " << fill << endl;
208     }
209   }
210
211   //   cout << "Matching completed" << endl;
212   return Stats;
213 }
214
215 //________________________________________________________________________________________________
216 void AliPSQAVisualization::ConvertTGraphErrorsToTH1Ds(){
217
218   cout << "********************** C O N V E R T I N G    TGRAPHS       T O      T H 1 D" << endl;
219
220   fRootFile = TFile::Open(Form("%s",fROOTInput.Data()));
221   cout << "Opening file " << fROOTInput.Data() << endl;
222
223   fDrawPlot = new TH1D[fNSelectedPlots]; // Array of TH1D's to be converted
224   fNDiffFills = new Int_t[fNSelectedPlots];
225   fFillSeparationLine = new TLine*[fNSelectedPlots];
226
227   for (Int_t iplot = 0; iplot < fNSelectedPlots; iplot++){
228     // Variables from the old TGraphErrors needed to draw TH1Fs
229     // Uncomment if seg fault returns TGraph::GetX (this=0x0), as last printout will say which graph is not correct
230     //    cout << fInDirectory.Data() << "/" << fROOTInput.Data() << ": " << fSelectedPlots[iplot].Data() << endl;
231     fNDiffFills[iplot] = 0;
232
233     // cout << "Problem is here? " << fSelectedPlots[iplot].Data() << endl;
234     TGraphErrors * TGEplot  = (TGraphErrors*) fRootFile->Get(fSelectedPlots[iplot].Data());
235     if(!TGEplot) {
236       //          cout << "Missing plot @ step " << iplot << "plot is -> " <<   fSelectedPlots[iplot].Data() << endl;
237       continue;
238     }
239           
240     Double_t     * TGEx     = TGEplot->GetX(); // needed to properly index the x-axis (run numbers)
241     Double_t     * TGEy     = TGEplot->GetY(); // array of double_t's, qaval
242     Int_t        TGEnpoints = TGEplot->GetN(); // number of points used in the TGE
243     Double_t      * TGEey   = TGEplot->GetEY(); // array of double_t's corresponding to the errors in the TGE
244     TString      TGEname    = TGEplot->GetName();
245     TString      TGEtitle   = TGEplot->GetTitle();
246
247     // TGEx = new Double_t[TGEnpoints];
248
249     fNRuns = TGEnpoints;
250     fRunNumbers = new Int_t[fNRuns];
251     fFillNumbers = new Int_t[fNRuns];
252     fBinArray = new Int_t[fNRuns];
253
254     for (Int_t irun=0; irun<TGEnpoints; irun++){
255       fRunNumbers[irun] = TGEx[irun];
256       fFillNumbers[irun] = MatchGoodRunToFillNumber(fRunNumbers[irun]);
257       cout << "Run number [" << irun << "] - " << fRunNumbers[irun] << " - " << fFillNumbers[irun] << endl;
258       fBinArray[irun] = irun;
259     }
260
261     // make tlines to identify different
262
263     // Parameters for the to be drawn TH1D
264     TString     TH1Dname  = TGEname.Data();
265     TH1Dname  += "_TH1D";
266     TString     TH1Dtitle = TGEtitle.Data();
267     TH1Dtitle += " TH1D";
268     // See Below for the strange numbering of bins
269     
270     Int_t       TH1Dxnbin = TGEnpoints;
271     Int_t       TH1Dxlow  = 1;
272     Int_t       TH1Dxhigh = TH1Dxnbin + 1;
273     // Declare the new plot to be drawn as a TH1D
274     
275     fDrawPlot[iplot].SetBins(TH1Dxnbin, TH1Dxlow, TH1Dxhigh); // start with bin label 1, up through bin number +1 (TH1D bin numbering has strange conventions, as zero bin is the underflow bin)
276     
277     fDrawPlot[iplot].SetNameTitle(TH1Dname.Data(),TH1Dtitle.Data());
278     fDrawPlot[iplot].GetXaxis()->SetTitle("Run Number");
279     TString TH1Dytitle = SetDrawSelectedYTitle(TGEtitle);
280     fDrawPlot[iplot].SetYTitle(TH1Dytitle.Data());
281
282     cout << "==================== TEST ============= " << endl;
283     cout << "-------------------- iplot = " << iplot << endl;
284
285     for (Int_t ibin = 1; ibin < TH1Dxnbin+1; ibin++){ // everything shifted off by one because tgraph starts at zero, th1f starts bins at 1
286       fDrawPlot[iplot].SetBinContent(fDrawPlot[iplot].FindBin(ibin),TGEy[ibin-1]); // y[i-1] is the bin in plot
287       fDrawPlot[iplot].SetBinError(fDrawPlot[iplot].FindBin(ibin),TGEey[ibin-1]);
288
289       if(ibin< TH1Dxnbin){
290         if(fFillNumbers[ibin]!=fFillNumbers[ibin-1]){
291           cout << "New fill @ " << ibin << endl;
292           cout << "Run @ "<< ibin-1 << " = " << fRunNumbers[ibin-1] <<" corresponding to fill " << fFillNumbers[ibin-1] << "; Crosscheck on bin array = " << fBinArray[ibin-1] << endl;
293           cout << "Run @ "<< ibin << " = " << fRunNumbers[ibin] <<" corresponding to fill " << fFillNumbers[ibin] << endl;
294           fNDiffFills[iplot]++;
295           cout << "****************************************" << endl;
296         }
297       }
298
299       Int_t TH1Dx = Int_t(TGEx[ibin-1]); // x[i-1] = actual bin label in plot
300       TString TH1DxBinLabel = Form("%i",TH1Dx);
301       
302       cout << "TH1DxBinLabel = " << TH1DxBinLabel << endl;
303
304       fDrawPlot[iplot].GetXaxis()->SetBinLabel(fDrawPlot[iplot].FindBin(ibin), TH1DxBinLabel.Data());
305       fDrawPlot[iplot].GetXaxis()->SetTitleSize(.05); // default = 4%, made it 5%
306
307     } // end of loop on bins
308     
309     fFillSeparationLine[iplot] = new TLine[fNDiffFills[iplot]];
310
311     TLine * newline = new TLine[fNDiffFills[iplot]];
312
313     cout << "Number of different fills = " << fNDiffFills[iplot] << " for iplot index = " << iplot << endl;
314     cout << "==================== END TEST ============= " << endl;
315
316     //looping again on the bins of the TGE -> filling the TLines
317
318     Int_t fillindex = 0;
319     for (Int_t ibin = 1; ibin < TH1Dxnbin+1; ibin++){
320
321       if(ibin<TH1Dxnbin){
322         if(fFillNumbers[ibin]!=fFillNumbers[ibin-1]){
323           //newline[fillindex].SetX1((0.5*(fFillNumbers[ibin-1]+fFillNumbers[ibin])));
324           //newline[fillindex].SetX2((0.5*(fFillNumbers[ibin-1]+fFillNumbers[ibin])));
325           // newline[fillindex].SetX1((0.5*((ibin-1)+ibin)));
326           // newline[fillindex].SetX2((0.5*((ibin-1)+ibin)));
327           newline[fillindex].SetX1(ibin+1);
328           newline[fillindex].SetX2(ibin+1);
329           newline[fillindex].SetY1(0.);
330           newline[fillindex].SetY2(1.);
331           cout << "setting line @  = " << ((0.5*((ibin-1)+ibin))) << endl;
332           
333           fFillSeparationLine[iplot][fillindex] = newline[fillindex];
334
335           fillindex++;
336         } // end if on checking different run numbers
337       }// end if            
338     }// endl loop on bins
339     
340
341     //
342     // adding some drawing options
343     //
344     fDrawPlot[iplot].SetMarkerStyle(20);
345     fDrawPlot[iplot].SetMarkerSize(1.4);
346     fDrawPlot[iplot].SetMarkerColor(kBlue);
347     fDrawPlot[iplot].SetLineColor(kBlue);
348     fDrawPlot[iplot].GetYaxis()->SetRangeUser(-0.001,1.05);
349     fDrawPlot[iplot].GetXaxis()->LabelsOption("V");
350   } // end loop on plots
351
352   cout << "********************** E N D     C O N V E R T I N G    TGRAPHS       T O      T H 1 D" << endl;
353
354 }
355
356 //________________________________________________________________________________________________
357 TString AliPSQAVisualization::SetDrawSelectedYTitle(TString TGEtitle){
358
359   Ssiz_t start  = 0;
360   Ssiz_t first_o = TGEtitle.First('o'); // o in over, lowercase o that appears first is the over
361   Ssiz_t first_f = TGEtitle.First('f');
362
363   TString label[2];
364   label[0] = TString(TGEtitle( start , first_o - start - 1)); // Shift one over from the 'h'
365   label[1] = TString(TGEtitle( first_o + 4, first_f - first_o - 4 ));  //Shift five over from the 'O' 
366
367   // Make this substitution to make legend smaller
368
369   if (label[1].Contains("Trigger class")){
370     label[1].ReplaceAll("Trigger class","All");
371   }
372
373   TString yTH1Dtitle = label[0];
374   yTH1Dtitle += " / ";
375   yTH1Dtitle += label[1];
376
377   return yTH1Dtitle;
378 }
379
380 //________________________________________________________________________________________________
381 void AliPSQAVisualization::ScaleMinAndMax(){ // Get maximum and minimum value of traghs to set bounds for overplot
382   Double_t tmp_max; // max values from tgraphs
383   Double_t tmp_min; // min values from tgraphs
384
385   for (Int_t iplot = 0; iplot < fNSelectedPlots; iplot++){ // Loop over the number of plots to be made 
386     // Set maximum
387     tmp_max = fDrawPlot[iplot].GetMaximum();
388     if (tmp_max > fMaximum){
389       fMaximum = tmp_max;
390     }
391     // Set minimum
392     tmp_min = fDrawPlot[iplot].GetMinimum();
393     if (tmp_max < fMinimum){
394       fMinimum = tmp_min;
395     }
396   }
397
398   // Set the min to be lower and max to be higher so that all points can be seen
399   fMaximum *= fMultMax;
400   fMinimum /= fDivMin;
401 }
402
403 //________________________________________________________________________________________________
404 void AliPSQAVisualization::MakeDir(TString dir){ // have to pass a private data member, kinda ugly, but otherwise use sentinel values or copy this function three times... taken from AliPSQA
405   TString mkDir = "mkdir -p ";
406   mkDir += dir.Data();
407   gSystem->Exec(mkDir); // mkdir for the cache/output
408 }
409
410 //________________________________________________________________________________________________
411 void AliPSQAVisualization::ImportRunAndFillInfo(const Char_t * listOfRunsAndFills){
412
413   Int_t run_num; //run number from list
414   ifstream input_runsandfill; //text file object
415   input_runsandfill.open(listOfRunsAndFills,ios::in );  //open the text file
416
417   Int_t NRuns = 0; //number of runs to be processed
418   while(input_runsandfill >> run_num) { // count number of runs
419     NRuns++;
420   }
421   input_runsandfill.close();
422   cout << "In total there are " << NRuns << " runs in file " << endl;
423
424   fNRawRuns = NRuns/3;
425   fRawFillNumbers = new Int_t[fNRawRuns];
426   fRawRunNumbers = new Int_t[fNRawRuns];
427   fRawRunStats = new Int_t[fNRawRuns];
428
429   input_runsandfill.open(listOfRunsAndFills,ios::in );
430
431   for(Int_t irun = 0; irun < fNRawRuns; irun++){
432     input_runsandfill >> fRawRunNumbers[irun] >> fRawFillNumbers[irun] >> fRawRunStats[irun];
433     cout << irun << " - " << fRawRunNumbers[irun] <<  " - " << fRawFillNumbers[irun] << " - stats = " << fRawRunStats[irun] <<  endl;
434   }
435   cout << "DONE " << endl;
436   input_runsandfill.close();
437   cout << "DONE DONE" << endl;
438 }
439
440 //________________________________________________________________________________________________
441 void AliPSQAVisualization::DrawSelected(Int_t iplot){
442   fCanvas[iplot].cd(); // write to this canvas first
443   fCanvas[iplot].SetBottomMargin(0.15); // default 0.15
444   fCanvas[iplot].SetRightMargin(0.02);
445   /*
446     cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> " << endl;
447     cout << "iplot = " << iplot << endl;
448     cout << "Number of different fills for this plot " << fNDiffFills[iplot] <<  endl;
449     cout << "Plot name " << fSelectedPlots[iplot] << endl;
450     cout << " " << endl;
451     // here run check
452     */
453   fDrawPlot[iplot].GetXaxis()->SetTitleOffset(1.6);
454
455   fDrawPlot[iplot].Draw("E P X0"); // draw the new plot to canvas
456
457   cout << "Drawing " << fSelectedPlots[iplot] << endl;
458
459   TLine * line = new TLine[fNDiffFills[iplot]];
460   for (Int_t lineIndex = 0; lineIndex < fNDiffFills[iplot]; lineIndex++){
461     //     cout << "Index pf plots that are processed = (" << iplot << "," << lineIndex << ")" << endl;
462     //   cout << "Copying line " << lineIndex << endl;
463     line[lineIndex] = fFillSeparationLine[iplot][lineIndex];
464     //  cout << "Copied - drawing line " << lineIndex << endl;
465     line[lineIndex].Draw("same");
466     //     cout << "Drawn line " << lineIndex << endl;
467     // cout << "*****************" << endl;
468   }// endl loop on bins
469    // cout << "COMPLETED " << endl;
470
471 }
472 //________________________________________________________________________________________________
473 void AliPSQAVisualization::DrawSameTriggerOnSameCA(Int_t iplot){
474     
475   Bool_t containsstring = kFALSE;
476
477   containsstring = fSelectedPlots[iplot].Contains("kINT7",TString::kExact);
478     
479   if(containsstring) cout << iplot << " - Sting " << fSelectedPlots[iplot] << " - contains string: yes " << endl;
480   else cout << iplot << " - Sting " << fSelectedPlots[iplot] << " - contains string: no " << endl;
481 }
482
483
484 //________________________________________________________________________________________________
485 void AliPSQAVisualization::DrawOverPlotCA(Int_t iplot){
486   if (iplot == 0){
487     fOverCanvas.cd();
488     fDrawPlot[iplot].SetMarkerColor(fColors[iplot]); // iplot == 0 for Color_t == white...
489     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
490     fDrawPlot[iplot].SetLineColor(fColors[iplot]);
491     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
492     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
493     fDrawPlot[iplot].GetYaxis()->SetTitle("");
494     fDrawPlot[iplot].GetYaxis()->SetRangeUser(fMinimum, fMaximum);
495     // adding fill lines
496     
497     // end adding fill lines
498     fDrawPlot[iplot].Draw("E P X0");
499   }
500   else if (iplot == (fNSelectedPlots - 1) ){ 
501     fOverCanvas.cd();
502     fDrawPlot[iplot].SetMarkerColor(fColors[iplot]);
503     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
504     fDrawPlot[iplot].SetLineColor(fColors[iplot]);
505     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
506     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
507     fDrawPlot[iplot].GetYaxis()->SetTitle("");
508     fDrawPlot[iplot].Draw("E P X0 SAME");
509     //    fOverLegend->Draw();
510   }
511   else{
512     fOverCanvas.cd();
513     fDrawPlot[iplot].SetMarkerColor(fColors[iplot]);
514     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
515     fDrawPlot[iplot].SetLineColor(fColors[iplot]);
516     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
517     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
518     fDrawPlot[iplot].GetYaxis()->SetTitle("");
519     fDrawPlot[iplot].Draw("E P X0 SAME");
520   }
521 }
522
523 //________________________________________________________________________________________________
524 void AliPSQAVisualization::DrawOverPlotNoCA(Int_t iplot){
525   if (iplot == 0){
526     fOverCanvas.cd();
527     fDrawPlot[iplot].SetMarkerColor(Color_t(iplot+1)); // iplot == 0 for Color_t == white...
528     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
529     fDrawPlot[iplot].SetLineColor(Color_t(iplot+1));
530     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
531     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
532     fDrawPlot[iplot].GetYaxis()->SetTitle("");
533     fDrawPlot[iplot].GetYaxis()->SetRangeUser(fMinimum, fMaximum);
534     fDrawPlot[iplot].Draw("E P X0");
535   }
536   else if (iplot == (fNSelectedPlots - 1) ){ 
537     fOverCanvas.cd();
538     fDrawPlot[iplot].SetMarkerColor(Color_t(iplot+1));
539     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
540     fDrawPlot[iplot].SetLineColor(Color_t(iplot+1));
541     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
542     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
543     fDrawPlot[iplot].GetYaxis()->SetTitle("");
544     fDrawPlot[iplot].Draw("E P X0 SAME");
545     fOverLegend->Draw();
546   }
547   else{
548     fOverCanvas.cd();
549     fDrawPlot[iplot].SetMarkerColor(Color_t(iplot+1));
550     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
551     fDrawPlot[iplot].SetLineColor(Color_t(iplot+1));
552     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
553     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
554     fDrawPlot[iplot].GetYaxis()->SetTitle("");
555     fDrawPlot[iplot].Draw("P SAME");
556   }
557 }
558
559 //________________________________________________________________________________________________
560 void AliPSQAVisualization::SaveToPDFSeparately(Int_t iplot){
561   cout << "Saving: " << fOutDirectory << "/" << fSelectedPlots[iplot] <<".pdf"<<endl;
562   fCanvas[iplot].SaveAs(Form("%s/%s.pdf",fOutDirectory.Data(),fSelectedPlots[iplot].Data()));
563 }
564
565 //________________________________________________________________________________________________
566 void AliPSQAVisualization::SavePDFs(Int_t iplot){
567   if ( iplot == 0 ){ // Open the PDF file if to be saved and save the first plot
568     fCanvas[iplot].Print(Form("%s/%s(",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
569   }
570   else if ( (iplot == (fNSelectedPlots - 1)) && (!fSaveOverPlotPDF) ){ // Close the PDF and save the last plot
571     fCanvas[iplot].Print(Form("%s/%s)",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
572     fCanvas[iplot].SaveAs(Form("%s/%s_%d.pdf",fOutDirectory.Data(),fOutPDFName.Data(),iplot));
573   }
574   else{ // Save the PDF with the inbetween plots
575     fCanvas[iplot].Print(Form("%s/%s",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
576   }
577 }
578
579 //________________________________________________________________________________________________
580 void AliPSQAVisualization::SaveOverPlotPDF(){
581   fOverCanvas.cd();
582   if (fSavePDFs){
583     fOverCanvas.Print(Form("%s/%s)",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
584   }
585   else{
586     fOverCanvas.Print(Form("%s/%s",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
587   }
588 }
589
590 //________________________________________________________________________________________________
591 void AliPSQAVisualization::SaveOverPlotEPS(){
592   fOverCanvas.cd();
593   fOverCanvas.Print(Form("%s/%s",fOutDirectory.Data(),fOutEPSName.Data()),"eps");
594 }
595
596 //________________________________________________________________________________________________
597
598