]>
Commit | Line | Data |
---|---|---|
2403d402 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
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 | **************************************************************************/ | |
15 | ||
16 | // Draw histograms/graphs with same name located in different directories | |
17 | // author: Eulogio Serradilla <eulogio.serradilla@cern.ch> | |
18 | ||
aa54def0 | 19 | #if !defined(__CINT__) || defined(__MAKECINT__) |
2403d402 | 20 | #include <TFile.h> |
21 | #include <TString.h> | |
22 | #include <TMath.h> | |
23 | #include <TCanvas.h> | |
24 | #include <TPad.h> | |
25 | #include <TLegend.h> | |
26 | #include <TH1.h> | |
27 | #include <TGraphErrors.h> | |
28 | #include <TKey.h> | |
29 | #include <TLine.h> | |
30 | #include <TStyle.h> | |
aa54def0 | 31 | #endif |
2403d402 | 32 | |
fea73140 | 33 | TGraphErrors* Divide(const TGraphErrors* grX1, const TGraphErrors* grX2, const TString& name); |
2403d402 | 34 | |
35 | void DrawDir(const TString& inputFile, | |
36 | const TString& graphName, | |
37 | const TString& refdir="", | |
38 | Double_t xmin = 0, | |
39 | Double_t xmax = 3.5, | |
40 | Double_t ymin = 0, | |
41 | Double_t ymax = 1., | |
42 | const TString& xtitle = "", | |
43 | const TString& ytitle = "", | |
44 | Int_t option = 1, | |
45 | const TString& canvasName = "c0", | |
46 | const TString& canvasTitle = "DrawDir") | |
47 | { | |
48 | // | |
49 | // draw histograms/graphs with same name located in different directories | |
50 | // if option = 0 no comparison, | |
51 | // if option = 1 draw a bottom pad with the comparison, and | |
1cb68411 | 52 | // if option = 2 draw the comparison in a different canvas |
2403d402 | 53 | // |
54 | const Int_t kMax = 10; // maximum number of subdirectories | |
55 | ||
56 | const Int_t kColor[kMax] = { kRed, kBlue, kOrange+1, kGreen-2, kGreen+2, kAzure, kViolet+10, kAzure+2, kOrange+2, kSpring-7 }; | |
57 | ||
aa54def0 | 58 | const Int_t kMarker[kMax] = { kFullCircle, kFullTriangleUp, kFullSquare, kFullTriangleDown, kOpenCircle, kOpenSquare, kOpenTriangleUp, kOpenDiamond, kOpenCross, kFullStar }; |
2403d402 | 59 | |
60 | TFile* finput = new TFile(inputFile.Data()); | |
61 | if (finput->IsZombie()) exit(1); | |
62 | ||
63 | // iterate over the list of keys | |
64 | ||
65 | TObject* obj[kMax]; | |
66 | TString* subdir[kMax]; | |
67 | obj[0] = 0; // reference object | |
68 | Int_t nDir = 0; | |
69 | if(option>0) nDir = 1; | |
70 | ||
71 | TIter next(finput->GetListOfKeys()); | |
72 | TKey* key = 0; | |
73 | while( (key = (TKey*)next()) && (nDir < kMax) ) | |
74 | { | |
75 | TString classname = key->GetClassName(); | |
76 | if(classname == "TDirectoryFile") | |
77 | { | |
78 | TObject* i = 0; | |
79 | finput->GetObject(Form("%s/%s;1", key->GetName(), graphName.Data()),i); | |
80 | if(i == 0) | |
81 | { | |
82 | finput->Error("GetObject","%s/%s not found", key->GetName(), graphName.Data()); | |
83 | exit(1); | |
84 | } | |
85 | else if(i->InheritsFrom("TH1") || i->InheritsFrom("TGraph")) | |
86 | { | |
87 | Int_t j = 0; | |
88 | ||
89 | if(option==0) j = nDir++; | |
90 | else if(TString(key->GetName()) != refdir) j = nDir++; | |
91 | ||
92 | obj[j] = i; | |
93 | (dynamic_cast<TAttLine*>(i))->SetLineColor(kColor[j]); | |
94 | (dynamic_cast<TAttMarker*>(i))->SetMarkerColor(kColor[j]); | |
95 | (dynamic_cast<TAttMarker*>(i))->SetMarkerStyle(kMarker[j]); | |
96 | subdir[j] = new TString(key->GetName()); | |
97 | } | |
98 | else | |
99 | { | |
100 | finput->Warning("GetObject", "%s does not contain %s", key->GetName(), graphName.Data()); | |
101 | } | |
102 | } | |
103 | } | |
104 | ||
105 | // compare w.r.t. reference data | |
106 | ||
107 | TGraphErrors* grDiv[kMax]; | |
108 | ||
109 | if(option > 0) | |
110 | { | |
111 | if(obj[0] == 0) | |
112 | { | |
113 | finput->Error("GetObject", "reference directory %s not found", refdir.Data()); | |
114 | for(Int_t i=0; i < nDir; ++i) delete subdir[i]; | |
115 | exit(1); | |
116 | } | |
117 | ||
118 | TGraphErrors* grY = 0; | |
119 | ||
120 | if(obj[0]->InheritsFrom("TH1")) | |
121 | { | |
122 | grY = new TGraphErrors(dynamic_cast<TH1*>(obj[0])); | |
123 | } | |
124 | else if(obj[0]->InheritsFrom("TGraph")) | |
125 | { | |
126 | grY = new TGraphErrors(*dynamic_cast<TGraphErrors*>(obj[0])); | |
127 | } | |
128 | ||
129 | TGraphErrors* grX = 0; | |
130 | ||
131 | for(Int_t i=1; i < nDir; ++i) | |
132 | { | |
133 | if(obj[i]->InheritsFrom("TH1")) | |
134 | { | |
135 | grX = new TGraphErrors(dynamic_cast<TH1*>(obj[i])); | |
136 | } | |
137 | else if(obj[i]->InheritsFrom("TGraph")) | |
138 | { | |
139 | grX = new TGraphErrors(*dynamic_cast<TGraphErrors*>(obj[i])); | |
140 | } | |
141 | ||
fea73140 | 142 | grDiv[i] = Divide(grX, grY, Form("%s_%s_Ratio", subdir[i]->Data(), obj[i]->GetName())); |
2403d402 | 143 | |
144 | grDiv[i]->SetLineColor(kColor[i]); | |
145 | grDiv[i]->SetMarkerColor(kColor[i]); | |
146 | grDiv[i]->SetMarkerStyle(kMarker[i]); | |
147 | ||
148 | delete grX; | |
149 | } | |
150 | ||
151 | delete grY; | |
152 | } | |
153 | ||
154 | // draw | |
155 | ||
aa54def0 | 156 | gStyle->SetPadTickX(1); |
157 | gStyle->SetPadTickY(1); | |
158 | gStyle->SetOptTitle(0); | |
159 | gStyle->SetOptStat(0); | |
2403d402 | 160 | |
161 | TCanvas* c0 = new TCanvas(canvasName.Data(), canvasTitle.Data()); | |
162 | ||
163 | if(option == 1) // create a top pad | |
164 | { | |
165 | TPad* top = new TPad("top", "Variable", 0, 0.25, 1, 1, 0, 0, 0); | |
166 | ||
167 | top->SetBottomMargin(0.); | |
168 | top->Draw(); | |
169 | ||
170 | top->cd(); | |
171 | ||
172 | TH1F* frm = top->DrawFrame(xmin, ymin , xmax, ymax); | |
173 | frm->GetYaxis()->SetTitle(ytitle); | |
174 | } | |
175 | else // only draw the frame | |
176 | { | |
177 | TH1F* frm = c0->DrawFrame(xmin, ymin , xmax, ymax); | |
178 | frm->GetXaxis()->SetTitle(xtitle); | |
179 | frm->GetYaxis()->SetTitle(ytitle); | |
180 | } | |
181 | ||
182 | // draw objects in current pad | |
183 | for(Int_t i=0; i < nDir; ++i) | |
184 | { | |
185 | if(obj[i]->InheritsFrom("TH1")) | |
186 | { | |
187 | obj[i]->Draw("same"); | |
188 | } | |
189 | else if(obj[i]->InheritsFrom("TGraph")) | |
190 | { | |
aa54def0 | 191 | obj[i]->Draw("zP"); |
2403d402 | 192 | } |
193 | } | |
194 | ||
195 | // build a legend | |
196 | TLegend* legend = new TLegend(0.5718391,0.6991525,0.8390805,0.8368644,0,"brNDC"); | |
197 | legend->SetTextSize(0.03); | |
198 | legend->SetFillColor(0); | |
199 | legend->SetBorderSize(0); | |
200 | ||
201 | for(Int_t i=0; i < nDir; ++i) | |
202 | { | |
203 | legend->AddEntry(obj[i], subdir[i]->Data(), "lp"); | |
204 | } | |
205 | ||
206 | legend->Draw(); | |
207 | ||
208 | if(option == 1) // create a bottom pad | |
209 | { | |
210 | c0->cd(); | |
211 | ||
212 | TPad* bottom = new TPad("bottom", "ratio", 0, 0, 1, 0.25, 0, 0, 0); | |
213 | ||
214 | bottom->SetBottomMargin(0.3); | |
215 | bottom->SetTopMargin(0.); | |
216 | bottom->Draw(); | |
217 | ||
218 | bottom->cd(); | |
219 | ||
220 | TH1F* frm = bottom->DrawFrame(xmin, 0.7 , xmax, 1.3); | |
221 | ||
222 | frm->GetXaxis()->SetLabelSize(0.13); | |
223 | frm->GetXaxis()->SetTitle(xtitle); | |
224 | frm->GetXaxis()->SetTitleSize(0.13); | |
225 | frm->GetYaxis()->SetTitle("Ratio"); | |
226 | frm->GetYaxis()->SetLabelSize(0.1); | |
227 | frm->GetYaxis()->SetTitleSize(0.12); | |
228 | frm->GetYaxis()->SetTitleOffset(0.3); | |
229 | } | |
230 | else if(option == 2) // create a new canvas | |
231 | { | |
232 | TCanvas* c1 = new TCanvas(Form("%s.Ratio",canvasName.Data()), Form("%s ratio",canvasTitle.Data())); | |
233 | ||
234 | TH1F* frm = c1->DrawFrame(xmin, 0.5 ,xmax, 1.5); | |
235 | frm->GetXaxis()->SetTitle(xtitle); | |
236 | frm->GetYaxis()->SetTitle("Ratio"); | |
aa54def0 | 237 | frm->GetYaxis()->SetTitleOffset(1.20); |
2403d402 | 238 | } |
239 | ||
240 | // draw comparison | |
241 | if(nDir>0 && option > 0) | |
242 | { | |
2403d402 | 243 | // draw a red line for the reference |
244 | TLine* ref = new TLine(xmin,1,xmax,1); | |
245 | ref->SetLineWidth(1); | |
246 | ref->SetLineColor(kColor[0]); | |
aa54def0 | 247 | ref->SetLineStyle(2); |
2403d402 | 248 | ref->Draw(); |
249 | ||
aa54def0 | 250 | for(Int_t i=1; i<nDir; ++i) |
251 | { | |
252 | grDiv[i]->Draw("zP"); | |
253 | } | |
254 | ||
2403d402 | 255 | if(option == 2) |
256 | { | |
257 | TLegend* legendRatio = new TLegend(0.5718391,0.6991525,0.8390805,0.8368644,0,"brNDC"); | |
258 | legendRatio->SetTextSize(0.03); | |
259 | legendRatio->SetFillColor(0); | |
260 | legendRatio->SetBorderSize(0); | |
261 | ||
262 | legendRatio->AddEntry(ref, subdir[0]->Data(), "l"); | |
263 | for(Int_t i=1; i < nDir; ++i) | |
264 | { | |
265 | legendRatio->AddEntry(grDiv[i], subdir[i]->Data(), "lp"); | |
266 | } | |
267 | ||
aa54def0 | 268 | legendRatio->SetTextFont(42); |
2403d402 | 269 | legendRatio->Draw(); |
270 | } | |
271 | } | |
272 | ||
273 | // release memory | |
274 | } | |
275 | ||
fea73140 | 276 | Double_t GuessErrorY(const TGraphErrors* gr, Double_t x0) |
2403d402 | 277 | { |
278 | // | |
fea73140 | 279 | // estimate error of gr(x0) with the closest point to x0 |
280 | // | |
281 | for(Int_t i=0; i<gr->GetN(); ++i) | |
282 | { | |
283 | Double_t x, y; | |
284 | gr->GetPoint(i, x, y); | |
285 | if(x >= x0) return gr->GetErrorY(i); | |
286 | } | |
287 | ||
288 | return 0; | |
289 | } | |
290 | ||
291 | TGraphErrors* Divide(const TGraphErrors* grX1, const TGraphErrors* grX2, const TString& name) | |
292 | { | |
293 | // | |
294 | // grX1/grX2 using grX2 as reference | |
2403d402 | 295 | // |
296 | TGraphErrors* grQ = new TGraphErrors(); | |
297 | grQ->SetName(name.Data()); | |
298 | ||
fea73140 | 299 | Double_t xmin = 0; |
300 | Double_t xmax = 0; | |
301 | Double_t y1 = 0; | |
302 | grX1->GetPoint(0, xmin, y1); | |
303 | grX1->GetPoint(grX1->GetN()-1, xmax, y1); | |
304 | ||
305 | for(Int_t i=0, j=0; i < grX2->GetN(); ++i) | |
2403d402 | 306 | { |
fea73140 | 307 | Double_t x2, y2; |
308 | grX2->GetPoint(i, x2, y2); | |
309 | ||
310 | if(x2 < xmin) continue; | |
311 | if(x2 > xmax) break; | |
312 | ||
313 | y1 = grX1->Eval(x2); | |
2403d402 | 314 | |
315 | if(y1 == 0 || y2 == 0) continue; | |
316 | ||
317 | Double_t r = y1/y2; | |
318 | ||
fea73140 | 319 | Double_t erry1 = GuessErrorY(grX1, x2); |
320 | Double_t erry2 = grX2->GetErrorY(i); | |
2403d402 | 321 | Double_t err = r*TMath::Sqrt(TMath::Power(erry1/y1,2)+TMath::Power(erry2/y2,2)); |
322 | ||
fea73140 | 323 | grQ->SetPoint(j, x2, r); |
324 | grQ->SetPointError(j++, grX2->GetErrorX(i), err); | |
2403d402 | 325 | } |
326 | ||
327 | return grQ; | |
328 | } |