Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TAdvancedGraphicsDialog.cxx
Go to the documentation of this file.
1 // @(#)root/fitpanel:$Id$
2 // Author: David Gonzalez Maline 11/12/2008
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TAdvancedGraphicsDialog //
15 // //
16 // Allows to create advanced graphics from the last fit made in the //
17 // fitpanel. This includes the scan graphics, the contour and the //
18 // confidence levels. //
19 //////////////////////////////////////////////////////////////////////////
20 
22 #include "TGraph.h"
23 #include "TAxis.h"
24 #include "TPad.h"
25 #include "TColor.h"
26 
27 #include "Fit/BinData.h"
28 #include "Math/IParamFunction.h"
29 #include "TGraphErrors.h"
30 #include "TGraph2DErrors.h"
31 
32 #include <sstream>
33 
34 #include <string>
35 
36 TAdvancedGraphicsDialog::TAdvancedGraphicsDialog(const TGWindow *p, const TGWindow *main):
37  TGTransientFrame(p, main, 10, 10, kVerticalFrame),
38  fFitter((TBackCompFitter *) TVirtualFitter::GetFitter())
39 {
40  // Creates the Advanced Graphics Dialog.
41 
42 
43  if (!p && !main) {
44  MakeZombie();
45  return;
46  }
47  SetCleanup(kDeepCleanup);
48 
49  fMainFrame = new TGVerticalFrame(this);
50 
51  fTab = new TGTab(fMainFrame, 10, 10);
52  fMainFrame->AddFrame(fTab, new TGLayoutHints(kLHintsExpandY | kLHintsExpandX, 5,5,5,0));
53  fTab->SetCleanup(kDeepCleanup);
54  fTab->Associate(this);
55 
56  // Add the first method to the dialog (Contour)
57  CreateContourFrame();
58  fTab->AddTab("Contour", fContourFrame);
59 
60  // Add the second method to the dialog (Scan)
61  CreateScanFrame();
62  fTab->AddTab("Scan", fScanFrame);
63 
64  CreateConfFrame();
65  fTab->AddTab("Conf Intervals", fConfFrame);
66 
67  TGCompositeFrame * frame = new TGHorizontalFrame(fMainFrame);
68 
69  fDraw = new TGTextButton(frame, "&Draw", kAGD_BDRAW);
70  fDraw->Associate(this);
71  frame->AddFrame(fDraw, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0));
72 
73  fClose = new TGTextButton(frame, "&Close", kAGD_BCLOSE);
74  fClose->Associate(this);
75  frame->AddFrame(fClose, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0));
76 
77  UInt_t width = 0, height = 0;
78  height = fClose->GetDefaultHeight();
79  width = TMath::Max(width, fClose->GetDefaultWidth());
80  frame->Resize((width + 20) * 2, height);
81 
82  fMainFrame->AddFrame(frame, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 5, 0));
83 
84  this->AddFrame(fMainFrame, new TGLayoutHints(kLHintsNormal | kLHintsExpandX,0,0,5,5));
85 
86  ConnectSlots();
87 
88  SetWindowName("Advanced Drawing Tools");
89 
90  // map all widgets and calculate size of dialog
91  MapSubwindows();
92 
93  width = GetDefaultWidth();
94  height = GetDefaultHeight();
95 
96  Resize(width, height);
97  MapWindow();
98 
99  // position relative to the parent's window
100  CenterOnParent();
101 
102  // make the message box non-resizable
103  SetWMSize(width, height);
104  SetWMSizeHints(width, height, width, height, 0, 0);
105 
106  SetMWMHints(kMWMDecorAll | kMWMDecorResizeH | kMWMDecorMaximize |
107  kMWMDecorMinimize | kMWMDecorMenu,
108  kMWMFuncAll | kMWMFuncResize | kMWMFuncMaximize |
109  kMWMFuncMinimize,
110  kMWMInputModeless);
111 
112  // popup dialog and wait till user replies
113  gClient->WaitFor(this);
114 }
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 /// Create the frame that contains all the necessary information for
118 /// the Contour method.
119 
120 void TAdvancedGraphicsDialog::CreateContourFrame()
121 {
122  fContourFrame = new TGVerticalFrame(fTab);
123  TGHorizontalFrame* frame = new TGHorizontalFrame(fContourFrame);
124 
125  TGLabel* label = new TGLabel(frame, "Number of Points: ");
126  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
127 
128  fContourPoints = new TGNumberEntry(frame, 40,
129  5, kAGD_SCANMIN,
130  TGNumberFormat::kNESInteger,
131  TGNumberFormat::kNEAPositive,
132  TGNumberFormat::kNELNoLimits);
133  fContourPoints->Resize(130, 20);
134  fContourPoints->GetNumberEntry()->SetToolTipText("Sets the number of points used for the contour");
135  frame->AddFrame(fContourPoints, new TGLayoutHints(kLHintsNormal, 8, 0, 5, 0));
136  fContourFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
137 
138  frame = new TGHorizontalFrame(fContourFrame);
139  label = new TGLabel(frame, "Parameter 1: ");
140  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
141 
142  fContourPar1 = new TGComboBox(frame, kAGD_CONTPAR1);
143  AddParameters(fContourPar1);
144  fContourPar1->Resize(130, 20);
145  fContourPar1->Associate(this);
146  TGListBox *lb = fContourPar1->GetListBox();
147  lb->Resize(lb->GetWidth(), 200);
148  frame->AddFrame(fContourPar1, new TGLayoutHints(kLHintsNormal, 37, 0, 5, 0));
149  fContourFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
150 
151  frame = new TGHorizontalFrame(fContourFrame);
152 
153  label = new TGLabel(frame, "Parameter 2: ");
154  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
155 
156  fContourPar2 = new TGComboBox(frame, kAGD_CONTPAR2);
157  AddParameters(fContourPar2);
158  fContourPar2->Select(kAGD_PARCOUNTER+1, kFALSE);
159  fContourPar2->Resize(130, 20);
160  fContourPar2->Associate(this);
161  lb = fContourPar2->GetListBox();
162  lb->Resize(lb->GetWidth(), 200);
163  frame->AddFrame(fContourPar2, new TGLayoutHints(kLHintsNormal, 37, 0, 5, 0));
164 
165  fContourFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
166 
167  frame = new TGHorizontalFrame(fContourFrame);
168 
169  label = new TGLabel(frame, "Confidence Level: ");
170  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
171 
172  fContourError = new TGNumberEntry(frame, 0.683, 5, kAGD_CONTERR,
173  TGNumberFormat::kNESRealThree,
174  TGNumberFormat::kNEANonNegative,
175  TGNumberFormat::kNELNoLimits);
176  fContourError->Resize(130, 20);
177  fContourError->GetNumberEntry()->SetToolTipText("Sets the contour confidence level");
178  frame->AddFrame(fContourError, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
179 
180  fContourFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 5));
181 
182  frame = new TGHorizontalFrame(fContourFrame);
183 
184  label = new TGLabel(frame, "Fill Colour: ");
185  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
186 
187  fContourColor = new TGColorSelect(frame, TColor::Number2Pixel(kYellow - 10), kAGD_CONTCOLOR);
188  frame->AddFrame(fContourColor, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
189 
190  fContourOver = new TGCheckButton(frame, "Superimpose", kAGD_CONTOVER);
191  fContourOver->SetToolTipText("If checked, the new contour will overlap the previous one");
192  frame->AddFrame(fContourOver, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
193 
194  fContourFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 5));
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// Create the frame that contains all the necessary information for
199 /// the Scan method.
200 
201 void TAdvancedGraphicsDialog::CreateScanFrame()
202 {
203  fScanFrame = new TGVerticalFrame(fTab);
204  TGHorizontalFrame* frame = new TGHorizontalFrame(fScanFrame);
205 
206  TGLabel* label = new TGLabel(frame, "Number of Points: ");
207  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
208 
209  fScanPoints = new TGNumberEntry(frame, 40,
210  5, kAGD_SCANMIN,
211  TGNumberFormat::kNESInteger,
212  TGNumberFormat::kNEAPositive,
213  TGNumberFormat::kNELNoLimits);
214  fScanPoints->Resize(140, 20);
215  fScanPoints->GetNumberEntry()->SetToolTipText("Sets the number of points used in the scan");
216  frame->AddFrame(fScanPoints, new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0));
217  fScanFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
218 
219  frame = new TGHorizontalFrame(fScanFrame);
220 
221  label = new TGLabel(frame, "Parameter: ");
222  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
223 
224  fScanPar = new TGComboBox(frame, kAGD_SCANPAR);
225  AddParameters(fScanPar);
226  fScanPar->Resize(140, 20);
227  fScanPar->Associate(this);
228  TGListBox *lb = fScanPar->GetListBox();
229  lb->Resize(lb->GetWidth(), 200);
230  frame->AddFrame(fScanPar, new TGLayoutHints(kLHintsNormal, 39, 0, 5, 0));
231  fScanFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
232 
233  frame = new TGHorizontalFrame(fScanFrame);
234  label = new TGLabel(frame, "Min: ");
235  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
236 
237  double val = fFitter->GetParameter( fScanPar->GetSelected() - kAGD_PARCOUNTER );
238  double err = fFitter->GetParError( fScanPar->GetSelected() - kAGD_PARCOUNTER );
239  fScanMin = new TGNumberEntry(frame, val - 2.*err ,
240  5, kAGD_SCANMIN,
241  TGNumberFormat::kNESRealFour,
242  TGNumberFormat::kNEAAnyNumber,
243  TGNumberFormat::kNELNoLimits);
244  fScanMin->Resize(70, 20);
245  fScanMin->GetNumberEntry()->SetToolTipText("Sets the minimum parameter value");
246  frame->AddFrame(fScanMin, new TGLayoutHints(kLHintsNormal, 2, 0, 5, 0));
247 
248  label = new TGLabel(frame, "Max: ");
249  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 35, 5, 5, 0));
250  fScanMax = new TGNumberEntry(frame, val + 2.*err,
251  5, kAGD_SCANMAX,
252  TGNumberFormat::kNESRealFour,
253  TGNumberFormat::kNEAAnyNumber,
254  TGNumberFormat::kNELNoLimits);
255  fScanMax->Resize(70, 20);
256  fScanMax->GetNumberEntry()->SetToolTipText("Sets the maximum parameter value");
257  frame->AddFrame(fScanMax, new TGLayoutHints(kLHintsNormal, 2, 0, 5, 0));
258  fScanFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
259 
260 }
261 
262 ////////////////////////////////////////////////////////////////////////////////
263 /// Create the frame that contains all the necessary information for
264 /// the Confidence Level method.
265 
266 void TAdvancedGraphicsDialog::CreateConfFrame()
267 {
268  fConfFrame = new TGVerticalFrame(fTab);
269  TGHorizontalFrame* frame = new TGHorizontalFrame(fConfFrame);
270 
271  TGLabel* label = new TGLabel(frame, "Confidence Level: ");
272  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
273 
274  fConfLevel = new TGNumberEntry(frame, 0.95,
275  5, kAGD_SCANMIN,
276  TGNumberFormat::kNESRealTwo,
277  TGNumberFormat::kNEAPositive,
278  TGNumberFormat::kNELLimitMinMax,
279  0, 0.9999);
280  fConfLevel->Resize(140, 20);
281  fConfLevel->GetNumberEntry()->SetToolTipText("Sets the value of the confidence level");
282  frame->AddFrame(fConfLevel, new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0));
283  fConfFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
284 
285  frame = new TGHorizontalFrame(fConfFrame);
286 
287  label = new TGLabel(frame, "Fill Colour: ");
288  frame->AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));
289 
290  fConfColor = new TGColorSelect(frame, TColor::Number2Pixel(kYellow - 10), kAGD_CONTCOLOR);
291  frame->AddFrame(fConfColor, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
292 
293  fConfFrame->AddFrame(frame, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 5));
294 }
295 
296 void TAdvancedGraphicsDialog::AddParameters(TGComboBox* comboBox)
297 {
298  // Add all the parameters of the VirtualFitter into a comboBox
299  // (helper method)
300 
301  for ( Int_t i = 0; i < fFitter->GetNumberTotalParameters(); ++i ) {
302  comboBox->AddEntry(fFitter->GetParName(i), kAGD_PARCOUNTER + i);
303  }
304  comboBox->Select(kAGD_PARCOUNTER, kFALSE);
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 /// Connect the slots (buttons mainly + specific methods)
309 
310 void TAdvancedGraphicsDialog::ConnectSlots()
311 {
312  // Buttons
313  fClose->Connect("Clicked()", "TAdvancedGraphicsDialog", this, "CloseWindow()");
314  fDraw->Connect("Clicked()", "TAdvancedGraphicsDialog", this, "DoDraw()");
315 
316  // Slots for the Scan method
317  fScanPar->Connect("Selected(Int_t)", "TAdvancedGraphicsDialog", this, "DoChangedScanPar(Int_t)");
318 }
319 
320 ////////////////////////////////////////////////////////////////////////////////
321 /// Changes the Min and Max default values of the scan method,
322 /// depending on the selected parameter.
323 
324 void TAdvancedGraphicsDialog::DoChangedScanPar(Int_t selected)
325 {
326  double val = fFitter->GetParameter( selected - kAGD_PARCOUNTER );
327  double err = fFitter->GetParError( selected - kAGD_PARCOUNTER );
328  fScanMin->SetNumber( val -2 * err );
329  fScanMax->SetNumber( val +2 * err );
330 }
331 
332 ////////////////////////////////////////////////////////////////////////////////
333 /// Calls the correspoding method, depending on the selected tab.
334 
335 void TAdvancedGraphicsDialog::DoDraw()
336 {
337  if ( fTab->GetCurrent() == 0 ) {
338  DrawContour();
339  } else if ( fTab->GetCurrent() == 1 ) {
340  DrawScan();
341  } else if ( fTab->GetCurrent() == 2 ) {
342  DrawConfidenceLevels();
343  }
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Generates all necessary data for the Contour method from its
348 /// tab. Then it call Virtual Fitter to perform it.
349 
350 void TAdvancedGraphicsDialog::DrawContour()
351 {
352  static TGraph * graph = 0;
353  std::string options;
354  if ( ! (fContourOver->GetState() == kButtonDown) ) {
355  if ( graph )
356  delete graph;
357  options = "ALF";
358  } else
359  options = "LF";
360  graph = new TGraph( static_cast<int>(fContourPoints->GetNumber()) );
361  Int_t par1 = fContourPar1->GetSelected() - kAGD_PARCOUNTER;
362  Int_t par2 = fContourPar2->GetSelected() - kAGD_PARCOUNTER;
363  if ( par1 == par2 ) {
364  Error("TAdvancedGraphicsDialog::DrawContour", "Parameters cannot be the same");
365  return;
366  }
367  // contour error is actually the desired confidence level
368  Double_t cl = fContourError->GetNumber();
369  fFitter->Contour( par1, par2, graph, cl);
370  graph->SetFillColor( TColor::GetColor( fContourColor->GetColor() ) );
371  graph->GetXaxis()->SetTitle( fFitter->GetParName(par1) );
372  graph->GetYaxis()->SetTitle( fFitter->GetParName(par2) );
373  graph->Draw( options.c_str() );
374  gPad->Update();
375 }
376 
377 ////////////////////////////////////////////////////////////////////////////////
378 /// Generates all necessary data for the Scan method from its
379 /// tab. Then it call Virtual Fitter to perform it.
380 
381 void TAdvancedGraphicsDialog::DrawScan()
382 {
383  static TGraph * graph = 0;
384  if ( graph )
385  delete graph;
386  graph = new TGraph( static_cast<int>(fScanPoints->GetNumber()) );
387  Int_t par = fScanPar->GetSelected() - kAGD_PARCOUNTER;
388  fFitter->Scan( par, graph,
389  fScanMin->GetNumber(),
390  fScanMax->GetNumber() );
391  graph->SetLineColor(kBlue);
392  graph->SetLineWidth(2);
393  graph->GetXaxis()->SetTitle(fFitter->GetParName(par) );
394  graph->GetYaxis()->SetTitle("FCN" );
395  graph->Draw("APL");
396  gPad->Update();
397 }
398 
399 ////////////////////////////////////////////////////////////////////////////////
400 /// Generates all necessary data for the Scan method from its
401 /// tab. Then it call Virtual Fitter to perform it.
402 
403 void TAdvancedGraphicsDialog::DrawConfidenceLevels()
404 {
405  const ROOT::Fit::FitResult& result = fFitter->GetFitResult();
406  const ROOT::Fit::FitResult::IModelFunction* function = result.FittedFunction();
407  const ROOT::Fit::BinData* data = dynamic_cast<const ROOT::Fit::BinData*>(&(fFitter->GetFitData()));
408  if ( !data )
409  {
410  Error("DrawConfidenceLevels","Unbinned data set cannot draw confidence levels.");
411  return;
412  }
413 
414  if ( !function )
415  {
416  Error("DrawConfidenceLevels","Fit Function does not exist!");
417  return;
418  }
419 
420  std::vector<Double_t> ci(data->Size());
421  result.GetConfidenceIntervals(*data, &ci[0], fConfLevel->GetNumber());
422 
423  if ( data->NDim() == 1 )
424  {
425  TGraphErrors* g = new TGraphErrors(ci.size());
426  for (unsigned int i = 0; i < ci.size(); ++i)
427  {
428  const Double_t *x = data->Coords(i);
429  const Double_t y = (*function)(x);
430  g->SetPoint(i, *x, y);
431  g->SetPointError(i, 0, ci[i]);
432  }
433  std::ostringstream os;
434  os << "Confidence Intervals with " << fConfLevel->GetNumber()
435  << " conf. band.";
436  g->SetTitle(os.str().c_str());
437  g->SetLineColor( TColor::GetColor( fConfColor->GetColor() ));
438  g->SetFillColor( TColor::GetColor( fConfColor->GetColor() ));
439  g->SetFillStyle(3001);
440  g->Draw("C3same");
441  } else if ( data->NDim() == 2 )
442  {
443  TGraph2DErrors* g = new TGraph2DErrors(ci.size());
444  for (unsigned int i = 0; i < ci.size(); ++i)
445  {
446  const Double_t *x = data->Coords(i);
447  const Double_t y = (*function)(x);
448  g->SetPoint(i, x[0], x[1], y);
449  g->SetPointError(i, 0, 0, ci[i]);
450  }
451  std::ostringstream os;
452  os << "Confidence Intervals with " << fConfLevel->GetNumber()
453  << " conf. band.";
454  g->SetTitle(os.str().c_str());
455  g->SetLineColor( TColor::GetColor( fConfColor->GetColor() ));
456  g->SetFillColor( TColor::GetColor( fConfColor->GetColor() ));
457  g->SetFillStyle(3001);
458  g->Draw("C3same");
459  }
460  gPad->Update();
461 }
462 
463 ////////////////////////////////////////////////////////////////////////////////
464 /// Cleanup dialog.
465 
466 TAdvancedGraphicsDialog::~TAdvancedGraphicsDialog()
467 {
468  Cleanup();
469 }