First version of the PS QA macros (K.McDermont,A.Kalweit,S.Bjelogrlic)
[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 {
18   // Initialize some private data members from AliPSQAV
19   fInDirectory = "";
20   fROOTInput = "";
21   fSavePDFs = kFALSE;
22   fOutDirectory = "";
23   fOutPDFName = ""; 
24   fOutEPSName = "";
25   fDrawOverPlot = kFALSE;
26   fOverPlotTitle = "";
27   fMaximum = -1000;
28   fMinimum =  1000;
29   fScaleAuto = kFALSE;
30   fUseColorArray = kFALSE;
31   fMultMax = 0;
32   fDivMin = 0;
33   InitializeColorArray("");
34   InitializeSelectedPlots("");
35 }
36
37 //________________________________________________________________________________________________
38 AliPSQAVisualization::~AliPSQAVisualization(){
39   delete[] fCanvas;
40   delete[] fDrawPlot;
41   delete[] fSelectedPlots;
42   delete[] fColors;
43   delete fOverLegend;
44 }
45
46 //________________________________________________________________________________________________
47 void AliPSQAVisualization::InitializeColorArray(const Char_t * listOfColors){ // Function to custom set color array used for plots, not essential
48   Color_t colors; //color enums from list
49   ifstream input_data_col; //text file object
50   input_data_col.open(listOfColors, ios::in );  //open the text file
51   Int_t Ncol = 0; //number of color names to be used
52   
53   while ( input_data_col >> colors ) { // count number of color names
54     Ncol++;
55   }
56   
57   fNColors = Ncol; // Set private data member to total color names to be used
58   input_data_col.close(); // reset the file
59
60   fColors = new Color_t [fNColors]; // initialize private data member with number of trig names
61   input_data_col.open(listOfColors, ios::in );
62   for (Int_t icol = 0; icol < fNColors; icol++){
63     input_data_col >> fColors[icol];
64   }
65
66   input_data_col.close();  
67 }
68
69 //________________________________________________________________________________________________
70 void AliPSQAVisualization::InitializeSelectedPlots(const Char_t * listOfPlots){
71   TString plotnames; //plot names from list
72   ifstream input_data_pn; //text file object
73         if(!listOfPlots) cout << "No list of plots" << endl;
74   input_data_pn.open(listOfPlots, ios::in );  //open the text file
75   Int_t Npn = 0; //number of plot names to be used
76   
77   while ( input_data_pn >> plotnames ) { // count number of plot names
78     Npn++;
79     }
80
81   fNSelectedPlots = Npn; // Set private data member to total plot names to be used
82   input_data_pn.close(); // reset the file
83         cout << "Number of selected plots = " << fNSelectedPlots << endl;
84   fSelectedPlots = new TString [fNSelectedPlots]; // initialize private data member with number of trig names
85   input_data_pn.open(listOfPlots, ios::in );
86   for (Int_t iplot = 0; iplot < fNSelectedPlots; iplot++){
87     input_data_pn >> fSelectedPlots[iplot];
88           
89           cout << "Plots to process :" << fSelectedPlots[iplot] << endl;
90           
91   }
92
93   input_data_pn.close();  
94 }
95
96 //________________________________________________________________________________________________
97 void AliPSQAVisualization::PostProcessQA(){
98
99         if(!fROOTInput) cout << "No .root file found" << endl;
100         
101         
102         //cout << "Sto morendo qua? 1" << endl;
103   gStyle->SetOptStat(0);
104   gStyle->SetPalette(1);
105   gStyle->SetFillColor(10);
106   gStyle->SetOptStat(0);
107   gStyle->SetOptTitle(1);
108    // do not use scientific notation for run number
109   TGaxis::SetMaxDigits(6);
110   //cout << "Sto morendo qua? 2" << endl;
111   ConvertTGraphErrorsToTH1Ds();  // Convert all plots to TH1D's from specified plot list
112   //cout << "Sto morendo qua? 3" << endl;
113   fCanvas = new TCanvas[fNSelectedPlots]; // Allocate memory for the canvases to draw PostProcessing
114   
115    
116   if ((fDrawOverPlot) || (fSaveOverPlotPDF) || (fSaveOverPlotEPS)){
117     fOverLegend = new TLegend(0.55,0.625,.75,.85);
118     if (fScaleAuto){
119       ScaleMinAndMax();
120     }
121   }
122
123   if ((fSavePDFs) || (fSaveOverPlotPDF) || (fSaveOverPlotEPS)){
124     FileStat_t dummy_filestat;
125     if (gSystem->GetPathInfo(fOutDirectory.Data(), dummy_filestat) == 1) { // cache directory does not exist
126       MakeDir(fOutDirectory);
127     }
128   }
129
130   for (Int_t iplot = 0; iplot < fNSelectedPlots; iplot++){ // Loop over the number of plots to be made pretty and drawn
131     DrawSelected(iplot); // Draw the Selected plots, decide later whether to have them open/save them
132   
133     if (fSavePDFs){ // Write the canvas to the PDF file if kTRUE
134       SavePDFs(iplot);
135     }
136
137     if (!fDrawSelected){ // Close the canvas if you do not want to see the plot
138       fCanvas[iplot].Close();
139     }
140
141     if ( (fDrawOverPlot) || (fSaveOverPlotPDF) || (fSaveOverPlotEPS) ) { // Set points and draw overplot if any are true
142       if (fUseColorArray){
143         DrawOverPlotCA(iplot);
144       }
145       else{
146         DrawOverPlotNoCA(iplot);
147       }
148     }
149     else if( (!fDrawOverPlot) && ( (fSaveOverPlotPDF) || (fSaveOverPlotEPS) ) ) { // Set the points to save to and/or pdf/eps but then close it outside the loop
150       if (fUseColorArray){
151         DrawOverPlotCA(iplot);
152       }
153       else{
154         DrawOverPlotNoCA(iplot);
155       }
156     }   
157   }
158
159   if (fSaveOverPlotPDF){ // Save the overplot to pdf
160     SaveOverPlotPDF();
161   }
162   if (fSaveOverPlotEPS){ // Save the overplot to eps
163     SaveOverPlotEPS();
164   }
165   if (!fDrawOverPlot){ // Close if you do not want to see it
166     fOverCanvas.Close();
167   }
168 }
169
170 //________________________________________________________________________________________________
171 void AliPSQAVisualization::ConvertTGraphErrorsToTH1Ds(){
172   
173         fRootFile = TFile::Open(Form("%s",fROOTInput.Data()));
174         
175         
176   fDrawPlot = new TH1D[fNSelectedPlots]; // Array of TH1D's to be converted
177   
178   for (Int_t iplot = 0; iplot < fNSelectedPlots; iplot++){
179     // Variables from the old TGraphErrors needed to draw TH1Fs
180     // Uncomment if seg fault returns TGraph::GetX (this=0x0), as last printout will say which graph is not correct
181     cout << fInDirectory.Data() << "/" << fROOTInput.Data() << ": " << fSelectedPlots[iplot].Data() << endl;
182
183           
184           
185           cout << "Problem is here? " << fSelectedPlots[iplot].Data() << endl;
186     TGraphErrors * TGEplot  = (TGraphErrors*) fRootFile->Get(fSelectedPlots[iplot].Data());
187           if(!TGEplot) {
188                   cout << "Missing plot : " <<   fSelectedPlots[iplot].Data() << endl;
189                   continue;
190           }
191           
192     Double_t     * TGEx     = TGEplot->GetX(); // needed to properly index the x-axis (run numbers)
193     Double_t     * TGEy     = TGEplot->GetY(); // array of double_t's, qaval
194     Int_t        TGEnpoints = TGEplot->GetN(); // number of points used in the TGE
195     Double_t      * TGEey   = TGEplot->GetEY(); // array of double_t's corresponding to the errors in the TGE
196     TString      TGEname    = TGEplot->GetName();  
197     TString      TGEtitle   = TGEplot->GetTitle(); 
198     // Parameters for the to be drawn TH1D
199     TString     TH1Dname  = TGEname.Data();
200     TH1Dname  += "_TH1D";
201     TString     TH1Dtitle = TGEtitle.Data();
202     TH1Dtitle += " TH1D";
203     // See Below for the strange numbering of bins
204
205     Int_t       TH1Dxnbin = TGEnpoints;
206     Int_t       TH1Dxlow  = 1;
207     Int_t       TH1Dxhigh = TH1Dxnbin + 1;
208     // Declare the new plot to be drawn as a TH1D
209     
210     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)
211
212     fDrawPlot[iplot].SetNameTitle(TH1Dname.Data(),TH1Dtitle.Data());
213     fDrawPlot[iplot].GetXaxis()->SetTitle("Run Number");
214     TString TH1Dytitle = SetDrawSelectedYTitle(TGEtitle);
215     fDrawPlot[iplot].SetYTitle(TH1Dytitle.Data());
216
217     for (Int_t ibin = 1; ibin < TH1Dxnbin+1; ibin++){ // everything shifted off by one because tgraph starts at zero, th1f starts bins at 1
218       fDrawPlot[iplot].SetBinContent(fDrawPlot[iplot].FindBin(ibin),TGEy[ibin-1]); // y[i-1] is the bin in plot
219       fDrawPlot[iplot].SetBinError(fDrawPlot[iplot].FindBin(ibin),TGEey[ibin-1]);
220       
221       Int_t TH1Dx = Int_t(TGEx[ibin-1]); // x[i-1] = actual bin label in plot
222       TString TH1DxBinLabel = Form("%i",TH1Dx);
223       fDrawPlot[iplot].GetXaxis()->SetBinLabel(fDrawPlot[iplot].FindBin(ibin), TH1DxBinLabel.Data());
224       fDrawPlot[iplot].GetXaxis()->SetTitleSize(.05); // default = 4%, made it 5%
225     }
226     //
227     // adding some drawing options
228     //
229     fDrawPlot[iplot].SetMarkerStyle(20);
230     fDrawPlot[iplot].SetMarkerSize(1.4);
231     fDrawPlot[iplot].SetMarkerColor(kBlue);
232     fDrawPlot[iplot].SetLineColor(kBlue);
233     fDrawPlot[iplot].GetYaxis()->SetRangeUser(-0.001,1.05);
234     fDrawPlot[iplot].GetXaxis()->LabelsOption("V");
235   }
236 }
237
238 //________________________________________________________________________________________________
239 TString AliPSQAVisualization::SetDrawSelectedYTitle(TString TGEtitle){
240   
241   Ssiz_t start  = 0;  
242   Ssiz_t first_o = TGEtitle.First('o'); // o in over, lowercase o that appears first is the over
243   Ssiz_t first_f = TGEtitle.First('f');
244
245   TString label[2];
246   label[0] = TString(TGEtitle( start , first_o - start - 1)); // Shift one over from the 'h'
247   label[1] = TString(TGEtitle( first_o + 4, first_f - first_o - 4 ));  //Shift five over from the 'O' 
248
249   // Make this substitution to make legend smaller
250   
251   if (label[1].Contains("Trigger class")){
252     label[1].ReplaceAll("Trigger class","All");
253   }
254
255   TString yTH1Dtitle = label[0];
256   yTH1Dtitle += " / ";
257   yTH1Dtitle += label[1];
258
259   return yTH1Dtitle;
260 }
261
262 //________________________________________________________________________________________________
263 void AliPSQAVisualization::ScaleMinAndMax(){ // Get maximum and minimum value of traghs to set bounds for overplot
264   Double_t tmp_max; // max values from tgraphs
265   Double_t tmp_min; // min values from tgraphs
266
267   for (Int_t iplot = 0; iplot < fNSelectedPlots; iplot++){ // Loop over the number of plots to be made 
268     // Set maximum
269     tmp_max = fDrawPlot[iplot].GetMaximum();
270     if (tmp_max > fMaximum){
271        fMaximum = tmp_max;
272     }
273     // Set minimum
274     tmp_min = fDrawPlot[iplot].GetMinimum();
275     if (tmp_max < fMinimum){
276       fMinimum = tmp_min;
277     }
278   }
279
280   // Set the min to be lower and max to be higher so that all points can be seen
281   fMaximum *= fMultMax;
282   fMinimum /= fDivMin;
283 }
284
285 //________________________________________________________________________________________________
286 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
287   TString mkDir = "mkdir -p ";
288   mkDir += dir.Data();
289   gSystem->Exec(mkDir); // mkdir for the cache/output
290 }
291
292 //________________________________________________________________________________________________
293 void AliPSQAVisualization::DrawSelected(Int_t iplot){
294    fCanvas[iplot].cd(); // write to this canvas first
295    fCanvas[iplot].SetBottomMargin(0.15); // default 0.15
296    fCanvas[iplot].SetRightMargin(0.02);
297    fDrawPlot[iplot].GetXaxis()->SetTitleOffset(1.6);
298    fDrawPlot[iplot].Draw("E P X0"); // draw the new plot to canvas
299 }
300
301 //________________________________________________________________________________________________
302 void AliPSQAVisualization::DrawOverPlotCA(Int_t iplot){
303   if (iplot == 0){
304     fOverCanvas.cd();
305     fDrawPlot[iplot].SetMarkerColor(fColors[iplot]); // iplot == 0 for Color_t == white...
306     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
307     fDrawPlot[iplot].SetLineColor(fColors[iplot]);
308     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
309     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
310     fDrawPlot[iplot].GetYaxis()->SetTitle("");
311     fDrawPlot[iplot].GetYaxis()->SetRangeUser(fMinimum, fMaximum);
312     fDrawPlot[iplot].Draw("E P X0");
313   }
314   else if (iplot == (fNSelectedPlots - 1) ){ 
315     fOverCanvas.cd();
316     fDrawPlot[iplot].SetMarkerColor(fColors[iplot]);
317     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
318     fDrawPlot[iplot].SetLineColor(fColors[iplot]);
319     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
320     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
321     fDrawPlot[iplot].GetYaxis()->SetTitle("");
322     fDrawPlot[iplot].Draw("E P X0 SAME");
323     //    fOverLegend->Draw();
324   }
325   else{
326     fOverCanvas.cd();
327     fDrawPlot[iplot].SetMarkerColor(fColors[iplot]);
328     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
329     fDrawPlot[iplot].SetLineColor(fColors[iplot]);
330     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
331     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
332     fDrawPlot[iplot].GetYaxis()->SetTitle("");
333     fDrawPlot[iplot].Draw("E P X0 SAME");
334   }
335 }
336
337 //________________________________________________________________________________________________
338 void AliPSQAVisualization::DrawOverPlotNoCA(Int_t iplot){
339   if (iplot == 0){
340     fOverCanvas.cd();
341     fDrawPlot[iplot].SetMarkerColor(Color_t(iplot+1)); // iplot == 0 for Color_t == white...
342     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
343     fDrawPlot[iplot].SetLineColor(Color_t(iplot+1));
344     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
345     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
346     fDrawPlot[iplot].GetYaxis()->SetTitle("");
347     fDrawPlot[iplot].GetYaxis()->SetRangeUser(fMinimum, fMaximum);
348     fDrawPlot[iplot].Draw("E P X0");
349   }
350   else if (iplot == (fNSelectedPlots - 1) ){ 
351     fOverCanvas.cd();
352     fDrawPlot[iplot].SetMarkerColor(Color_t(iplot+1));
353     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
354     fDrawPlot[iplot].SetLineColor(Color_t(iplot+1));
355     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
356     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
357     fDrawPlot[iplot].GetYaxis()->SetTitle("");
358     fDrawPlot[iplot].Draw("E P X0 SAME");
359     fOverLegend->Draw();
360   }
361   else{
362     fOverCanvas.cd();
363     fDrawPlot[iplot].SetMarkerColor(Color_t(iplot+1));
364     fDrawPlot[iplot].SetMarkerStyle(Style_t(iplot+20)); // 20 = big circle, afterwards, useful styles, otherwise too small
365     fDrawPlot[iplot].SetLineColor(Color_t(iplot+1));
366     fDrawPlot[iplot].SetTitle(fOverPlotTitle);
367     fOverLegend->AddEntry(&fDrawPlot[iplot],fDrawPlot[iplot].GetYaxis()->GetTitle(),"lep");
368     fDrawPlot[iplot].GetYaxis()->SetTitle("");
369     fDrawPlot[iplot].Draw("P SAME");
370   }
371 }
372
373 //________________________________________________________________________________________________
374 void AliPSQAVisualization::SavePDFs(Int_t iplot){
375   if ( iplot == 0 ){ // Open the PDF file if to be saved and save the first plot
376     fCanvas[iplot].Print(Form("%s/%s(",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
377           
378   }
379   else if ( (iplot == (fNSelectedPlots - 1)) && (!fSaveOverPlotPDF) ){ // Close the PDF and save the last plot
380     fCanvas[iplot].Print(Form("%s/%s)",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
381             fCanvas[iplot].SaveAs(Form("%s/%s_%d.pdf",fOutDirectory.Data(),fOutPDFName.Data(),iplot));
382   }
383   else{ // Save the PDF with the inbetween plots
384     fCanvas[iplot].Print(Form("%s/%s",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
385   }
386 }
387
388 //________________________________________________________________________________________________
389 void AliPSQAVisualization::SaveOverPlotPDF(){
390   fOverCanvas.cd();
391   if (fSavePDFs){
392     fOverCanvas.Print(Form("%s/%s)",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
393         
394   }
395   else{
396     fOverCanvas.Print(Form("%s/%s",fOutDirectory.Data(),fOutPDFName.Data()),"pdf");
397   }
398 }
399
400 //________________________________________________________________________________________________
401 void AliPSQAVisualization::SaveOverPlotEPS(){
402   fOverCanvas.cd();
403   fOverCanvas.Print(Form("%s/%s",fOutDirectory.Data(),fOutEPSName.Data()),"eps");
404 }
405