1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 // Draw histograms/graphs with same name located in different directories
17 // author: Eulogio Serradilla <eulogio.serradilla@cern.ch>
27 #include <TGraphErrors.h>
32 TGraphErrors* Divide(const TGraphErrors* grX1, const TGraphErrors* grX2, const TString& name);
34 void DrawDir(const TString& inputFile,
35 const TString& graphName,
36 const TString& refdir="",
41 const TString& xtitle = "",
42 const TString& ytitle = "",
44 const TString& canvasName = "c0",
45 const TString& canvasTitle = "DrawDir")
48 // draw histograms/graphs with same name located in different directories
49 // if option = 0 no comparison,
50 // if option = 1 draw a bottom pad with the comparison, and
51 // if option = 2 draw the comparison in a different canvas
53 const Int_t kMax = 10; // maximum number of subdirectories
55 const Int_t kColor[kMax] = { kRed, kBlue, kOrange+1, kGreen-2, kGreen+2, kAzure, kViolet+10, kAzure+2, kOrange+2, kSpring-7 };
57 const Int_t kMarker[kMax] = { kFullCircle, kFullCircle, kFullCircle, kFullCircle, kOpenCircle, kOpenSquare, kOpenTriangleUp, kOpenDiamond, kOpenCross, kFullStar };
59 TFile* finput = new TFile(inputFile.Data());
60 if (finput->IsZombie()) exit(1);
62 // iterate over the list of keys
65 TString* subdir[kMax];
66 obj[0] = 0; // reference object
68 if(option>0) nDir = 1;
70 TIter next(finput->GetListOfKeys());
72 while( (key = (TKey*)next()) && (nDir < kMax) )
74 TString classname = key->GetClassName();
75 if(classname == "TDirectoryFile")
78 finput->GetObject(Form("%s/%s;1", key->GetName(), graphName.Data()),i);
81 finput->Error("GetObject","%s/%s not found", key->GetName(), graphName.Data());
84 else if(i->InheritsFrom("TH1") || i->InheritsFrom("TGraph"))
88 if(option==0) j = nDir++;
89 else if(TString(key->GetName()) != refdir) j = nDir++;
92 (dynamic_cast<TAttLine*>(i))->SetLineColor(kColor[j]);
93 (dynamic_cast<TAttMarker*>(i))->SetMarkerColor(kColor[j]);
94 (dynamic_cast<TAttMarker*>(i))->SetMarkerStyle(kMarker[j]);
95 subdir[j] = new TString(key->GetName());
99 finput->Warning("GetObject", "%s does not contain %s", key->GetName(), graphName.Data());
104 // compare w.r.t. reference data
106 TGraphErrors* grDiv[kMax];
112 finput->Error("GetObject", "reference directory %s not found", refdir.Data());
113 for(Int_t i=0; i < nDir; ++i) delete subdir[i];
117 TGraphErrors* grY = 0;
119 if(obj[0]->InheritsFrom("TH1"))
121 grY = new TGraphErrors(dynamic_cast<TH1*>(obj[0]));
123 else if(obj[0]->InheritsFrom("TGraph"))
125 grY = new TGraphErrors(*dynamic_cast<TGraphErrors*>(obj[0]));
128 TGraphErrors* grX = 0;
130 for(Int_t i=1; i < nDir; ++i)
132 if(obj[i]->InheritsFrom("TH1"))
134 grX = new TGraphErrors(dynamic_cast<TH1*>(obj[i]));
136 else if(obj[i]->InheritsFrom("TGraph"))
138 grX = new TGraphErrors(*dynamic_cast<TGraphErrors*>(obj[i]));
141 grDiv[i] = Divide(grX, grY, Form("%s_%s_Ratio", subdir[i]->Data(), obj[i]->GetName()));
143 grDiv[i]->SetLineColor(kColor[i]);
144 grDiv[i]->SetMarkerColor(kColor[i]);
145 grDiv[i]->SetMarkerStyle(kMarker[i]);
155 TStyle* st = new TStyle();
165 st->SetCanvasColor(0);
166 st->SetFrameBorderMode(0);
167 st->SetFrameFillColor(0);
168 st->SetTitleFillColor(0);
169 st->SetLabelFont(62,"XYZ");
170 st->SetTitleFont(62,"XYZ");
175 TCanvas* c0 = new TCanvas(canvasName.Data(), canvasTitle.Data());
177 if(option == 1) // create a top pad
179 TPad* top = new TPad("top", "Variable", 0, 0.25, 1, 1, 0, 0, 0);
181 top->SetBottomMargin(0.);
186 TH1F* frm = top->DrawFrame(xmin, ymin , xmax, ymax);
187 frm->GetYaxis()->SetTitle(ytitle);
189 else // only draw the frame
191 TH1F* frm = c0->DrawFrame(xmin, ymin , xmax, ymax);
192 frm->GetXaxis()->SetTitle(xtitle);
193 frm->GetYaxis()->SetTitle(ytitle);
196 // draw objects in current pad
197 for(Int_t i=0; i < nDir; ++i)
199 if(obj[i]->InheritsFrom("TH1"))
201 obj[i]->Draw("same");
203 else if(obj[i]->InheritsFrom("TGraph"))
210 TLegend* legend = new TLegend(0.5718391,0.6991525,0.8390805,0.8368644,0,"brNDC");
211 legend->SetTextSize(0.03);
212 legend->SetFillColor(0);
213 legend->SetBorderSize(0);
215 for(Int_t i=0; i < nDir; ++i)
217 legend->AddEntry(obj[i], subdir[i]->Data(), "lp");
222 if(option == 1) // create a bottom pad
226 TPad* bottom = new TPad("bottom", "ratio", 0, 0, 1, 0.25, 0, 0, 0);
228 bottom->SetBottomMargin(0.3);
229 bottom->SetTopMargin(0.);
234 TH1F* frm = bottom->DrawFrame(xmin, 0.7 , xmax, 1.3);
236 frm->GetXaxis()->SetLabelSize(0.13);
237 frm->GetXaxis()->SetTitle(xtitle);
238 frm->GetXaxis()->SetTitleSize(0.13);
239 frm->GetYaxis()->SetTitle("Ratio");
240 frm->GetYaxis()->SetLabelSize(0.1);
241 frm->GetYaxis()->SetTitleSize(0.12);
242 frm->GetYaxis()->SetTitleOffset(0.3);
244 else if(option == 2) // create a new canvas
246 TCanvas* c1 = new TCanvas(Form("%s.Ratio",canvasName.Data()), Form("%s ratio",canvasTitle.Data()));
248 TH1F* frm = c1->DrawFrame(xmin, 0.5 ,xmax, 1.5);
249 frm->GetXaxis()->SetTitle(xtitle);
250 frm->GetYaxis()->SetTitle("Ratio");
254 if(nDir>0 && option > 0)
256 for(Int_t i=1; i<nDir; ++i)
258 grDiv[i]->Draw("PZ");
261 // draw a red line for the reference
262 TLine* ref = new TLine(xmin,1,xmax,1);
263 ref->SetLineWidth(1);
264 ref->SetLineColor(kColor[0]);
269 TLegend* legendRatio = new TLegend(0.5718391,0.6991525,0.8390805,0.8368644,0,"brNDC");
270 legendRatio->SetTextSize(0.03);
271 legendRatio->SetFillColor(0);
272 legendRatio->SetBorderSize(0);
274 legendRatio->AddEntry(ref, subdir[0]->Data(), "l");
275 for(Int_t i=1; i < nDir; ++i)
277 legendRatio->AddEntry(grDiv[i], subdir[i]->Data(), "lp");
287 Double_t GuessErrorY(const TGraphErrors* gr, Double_t x0)
290 // estimate error of gr(x0) with the closest point to x0
292 for(Int_t i=0; i<gr->GetN(); ++i)
295 gr->GetPoint(i, x, y);
296 if(x >= x0) return gr->GetErrorY(i);
302 TGraphErrors* Divide(const TGraphErrors* grX1, const TGraphErrors* grX2, const TString& name)
305 // grX1/grX2 using grX2 as reference
307 TGraphErrors* grQ = new TGraphErrors();
308 grQ->SetName(name.Data());
313 grX1->GetPoint(0, xmin, y1);
314 grX1->GetPoint(grX1->GetN()-1, xmax, y1);
316 for(Int_t i=0, j=0; i < grX2->GetN(); ++i)
319 grX2->GetPoint(i, x2, y2);
321 if(x2 < xmin) continue;
326 if(y1 == 0 || y2 == 0) continue;
330 Double_t erry1 = GuessErrorY(grX1, x2);
331 Double_t erry2 = grX2->GetErrorY(i);
332 Double_t err = r*TMath::Sqrt(TMath::Power(erry1/y1,2)+TMath::Power(erry2/y2,2));
334 grQ->SetPoint(j, x2, r);
335 grQ->SetPointError(j++, grX2->GetErrorX(i), err);