Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TFitEditor.cxx
Go to the documentation of this file.
1// @(#)root/fitpanel:$Id: ed8d59036b6a51c67cd739c2c75aa7780b847bf8 $
2// Author: Ilka Antcheva, Lorenzo Moneta 10/08/2006
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/** \class TFitEditor
14 \ingroup fitpanel
15
16
17Allows to perform, explore and compare various fits.
18
19To display the new Fit panel interface right click on a histogram
20or a graph to pop up the context menu and then select the menu
21entry 'Fit Panel'.
22
23"General" Tab
24
25The first set of GUI elements is related to the function choice
26and settings. The status bar on the bottom provides information
27about the current minimization settings using the following
28abbreviations:
29LIB - shows the current choice between Minuit/Minuit2/Fumili
30MIGRAD or FUMILI points to the current minimization method in use.
31Itr: - shows the maximum number of iterations nnnn set for the fit.
32Prn: - can be DEF/VER/QT and shows the current print option in use.
33
34"Predefined" combo box - contains a list of predefined functions
35in ROOT. The default one is Gaussian.
36
37"Operation" radio button group defines selected operational mode
38between functions: NOP - no operation (default); ADD - addition
39CONV - convolution (will be implemented in the future).
40
41Users can enter the function expression in a text entry field.
42The entered string is checked after Enter key was pressed. An
43error message shows up if the string is not accepted. The current
44prototype is limited and users have no freedom to enter file/user
45function names in this field.
46
47"Set Parameters" button opens a dialog for parameters settings.
48
49"Fit Settings" provides user interface elements related to the
50fitter. Currently there are two method choices: Chi-square and
51Binned Likelihood.
52
53"Linear Fit" check button sets the use of Linear fitter is it is
54selected. Otherwise the option 'F' is applied if polN is selected.
55"Robust" number entry sets the robust value when fitting graphs.
56"No Chi-square" check button sets ON/OFF option 'C' - do not
57calculate Chi-square (for Linear fitter).
58
59Fit options:
60"Integral" check button switch ON/OFF option 'I' - use integral
61of function instead of value in bin center.
62"Best Errors" sets ON/OFF option 'E' - better errors estimation
63using Minos technique.
64"All weights = 1" sets ON/OFF option 'W' - all weights set to 1,
65excluding empty bins and ignoring error bars.
66"Empty bins, weights=1" sets ON/OFF option 'WW' - all weights
67equal to 1, including empty bins, error bars ignored.
68"Use range" sets ON/OFF option 'R' - fit only data within the
69specified function range with the slider.
70"Improve fit results" sets ON/OFF option 'M' - after minimum is
71found, search for a new one.
72"Add to list" sets On/Off option '+'- add function to the list
73without deleting the previous.
74
75Draw options:
76"SAME" sets On/Off function drawing on the same pad.
77"No drawing" sets On/Off option '0'- do not draw function graphics.
78"Do not store/draw" sets On/Off option 'N'- do not store the
79function, do not draw it.
80
81Sliders settings are used if option 'R' - use range is active.
82Users can change min/max values by pressing the left mouse button
83near to the left/right slider edges. It is possible o change both
84values simultaneously by pressing the left mouse button near to its
85center and moving it to a new desire position.
86
87"Minimization" Tab
88
89"Library" group allows you to use Minuit, Minuit2 or Fumili
90minimization packages for your fit.
91 "Minuit" - the popular Minuit minimization package.
92 "Minuit2" - a new object-oriented implementation of Minuit in C++.
93 "Fumili" - the popular Fumili minimization package.
94
95"Method" group has currently restricted functionality.
96 "MIGRAD" method is available for Minuit and Minuit2
97 "FUMILI" method is available for Fumili and Minuit2
98 "SIMPLEX" method is disabled (will come with the new fitter design)
99
100"Minimization Settings' group allows users to set values for:
101 "Error definition" - between 0.0 and 100.0 (default is 1.0).
102 "Maximum tolerance" - the fit relative precision in use.
103 "Maximum number of iterations" - default is 5000.
104
105Print options:
106 "Default" - between Verbose and Quiet.
107 "Verbose" - prints results after each iteration.
108 "Quiet" - no fit information is printed.
109
110Fit button - performs a fit.
111Reset - resets all GUI elements and related fit settings to the
112default ones.
113Close - closes this window.
114
115*/
116
117
118#include "TFitEditor.h"
119#include "TROOT.h"
120#include "TClass.h"
121#include "TCanvas.h"
122#include "TGTab.h"
123#include "TGLabel.h"
124#include "TG3DLine.h"
125#include "TGComboBox.h"
126#include "TGTextEntry.h"
127#include "TGGC.h"
128#include "TGButtonGroup.h"
129#include "TGNumberEntry.h"
130#include "TGDoubleSlider.h"
131#include "TGStatusBar.h"
132#include "TFitParametersDialog.h"
133#include "TGMsgBox.h"
134#include "TAxis.h"
135#include "TGraph.h"
136#include "TGraph2D.h"
137#include "TH1.h"
138#include "TH2.h"
139#include "HFitInterface.h"
140#include "TF1.h"
141#include "TF1NormSum.h"
142#include "TF1Convolution.h"
143#include "TF2.h"
144#include "TF3.h"
145#include "THStack.h"
146#include "Fit/UnBinData.h"
147#include "Fit/BinData.h"
148#include "TMultiGraph.h"
149#include "TTree.h"
150#include "TVirtualTreePlayer.h"
151#include "TSelectorDraw.h"
152#include "TTreeInput.h"
154#include "TVirtualX.h"
155#include "strlcpy.h"
156
157#include "RConfigure.h"
158#include "TPluginManager.h"
159
160#include <vector>
161#include <queue>
162using std::vector;
163using std::pair;
164
165#include "CommonDefs.h"
166
167// #include <iostream>
168// using std::cout;
169// using std::endl;
170
171void SearchCanvases(TSeqCollection* canvases, std::vector<TObject*>& objects);
172
173typedef std::multimap<TObject*, TF1*> FitFuncMap_t;
174
175////////////////////////////////////////////////////////////////////////////////
176/// This method looks among the functions stored by the fitpanel, the
177/// one that is currently selected in the fFuncList
178
180{
181 // Get the title/name of the function from fFuncList
182 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
183 if ( !te ) return 0;
184 TString name(te->GetTitle());
185
186 // Look for a system function if it's USER DEFINED function
187 if ( fTypeFit->GetSelected() == kFP_UFUNC ) {
188 for (auto f : fSystemFuncs) {
189 if ( strcmp( f->GetName(), name ) == 0 )
190 // If found, return it.
191 return f;
192 }
193 // If we are looking for previously fitted functions, look in the
194 // fPrevFit data structure.
195 } else if ( fTypeFit->GetSelected() == kFP_PREVFIT ) {
196 std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(fFitObject);
197 for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
198 TF1* f = it->second;
199 if ( strcmp( f->GetName(), name ) == 0 )
200 // If found, return it
201 return f;
202 }
203 }
204
205 // Return a pointer to null if the function does not exist. This
206 // will eventually create a segmentation fault, but the line should
207 // never be executed.
208 return 0;
209}
210
211////////////////////////////////////////////////////////////////////////////////
212///Copies f into a new TF1 to be stored in the fitpanel with it's
213///own ownership. This is taken from Fit::StoreAndDrawFitFunction in
214///HFitImpl.cxx
215
217{
218 double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
219
220 // no need to use kNotGlobal bit. TF1::Copy does not add in the list by default
221 if ( dynamic_cast<TF3 *>(f) != 0 ) {
222 TF3* fnew = (TF3 *)f->IsA()->New();
223 f->Copy(*fnew);
224 f->GetRange(xmin,ymin,zmin,xmax,ymax,zmax);
225 fnew->SetRange(xmin,ymin,zmin,xmax,ymax,zmax);
226 fnew->SetParent( nullptr );
227 fnew->AddToGlobalList(false);
228 return fnew;
229 } else if ( dynamic_cast<TF2 *>(f) != 0 ) {
230 TF2* fnew = (TF2 *)f->IsA()->New();
231 f->Copy(*fnew);
232 f->GetRange(xmin,ymin,xmax,ymax);
233 fnew->SetRange(xmin,ymin,xmax,ymax);
234 fnew->Save(xmin,xmax,ymin,ymax,0,0);
235 fnew->SetParent( nullptr );
236 fnew->AddToGlobalList(false);
237 return fnew;
238 } else {
239 TF1* fnew = (TF1 *)f->IsA()->New();
240 f->Copy(*fnew);
241 f->GetRange(xmin,xmax);
242 fnew->SetRange(xmin,xmax);
243 // This next line is added, as fnew-Save fails with gausND! As
244 // the number of dimensions is unknown...
245 if ( '\0' != fnew->GetExpFormula()[0] )
246 fnew->Save(xmin,xmax,0,0,0,0);
247 fnew->SetParent( nullptr );
248 fnew->AddToGlobalList(false);
249 return fnew;
250 }
251}
252
253////////////////////////////////////////////////////////////////////////////////
254/// Stores the parameters of the given function into pars
255
257{
258 int npar = func->GetNpar();
259 if (npar != (int) pars.size() ) pars.resize(npar);
260 for ( Int_t i = 0; i < npar; ++i )
261 {
262 Double_t par_min, par_max;
263 pars[i][PAR_VAL] = func->GetParameter(i);
264 func->GetParLimits(i, par_min, par_max);
265 pars[i][PAR_MIN] = par_min;
266 pars[i][PAR_MAX] = par_max;
267 }
268}
269
270////////////////////////////////////////////////////////////////////////////////
271/// Restore the parameters from pars into the function
272
274{
275 int npar = func->GetNpar();
276 if (npar > (int) pars.size() ) pars.resize(npar);
277 for ( Int_t i = 0; i < npar; ++i )
278 {
279 func->SetParameter(i, pars[i][PAR_VAL]);
280 func->SetParLimits(i, pars[i][PAR_MIN], pars[i][PAR_MAX]);
281 }
282}
283
284////////////////////////////////////////////////////////////////////////////////
285/// Parameter initialization for the function
286
287template<class FitObject>
288void InitParameters(TF1* func, FitObject * fitobj)
289{
290 const int special = func->GetNumber();
291 if (100 == special || 400 == special) {
293 ROOT::Fit::FillData(data,fitobj,func);
294 ROOT::Fit::InitGaus(data, func);
295 // case gaussian or Landau
296 } else if ( 110 == special || 410 == special ) {
298 ROOT::Fit::FillData(data,fitobj,func);
299 ROOT::Fit::Init2DGaus(data,func);
300 }
301}
302
303////////////////////////////////////////////////////////////////////////////////
304/// Splits the entry in fDataSet to get the selected variables and cuts
305/// from the text.
306
307void GetTreeVarsAndCuts(TGComboBox* dataSet, TString& variablesStr, TString& cutsStr)
308{
309 // Get the entry
310 TGTextLBEntry* textEntry =
311 static_cast<TGTextLBEntry*>( dataSet->GetListBox()->GetEntry( dataSet->GetSelected() ) );
312 if (!textEntry) return;
313 // Get the name of the tree
314 TString nameStr ( textEntry->GetText()->GetString() );
315 // Get the variables selected
316 variablesStr = nameStr(nameStr.First('(') + 2, nameStr.First(',') - nameStr.First('(') - 3);
317 // Get the cuts selected
318 cutsStr = nameStr( nameStr.First(',') + 3, nameStr.First(')') - nameStr.First(',') - 4 );
319}
320
321
322
324
325////////////////////////////////////////////////////////////////////////////////
326/// Static method - opens the fit panel.
327
329{
330 // Get the default pad if not provided.
331 if (!pad)
332 {
333 if (!gPad)
334 gROOT->MakeDefCanvas();
335 pad = gPad;
336 }
337
338 if (!fgFitDialog) {
339 fgFitDialog = new TFitEditor(pad, obj);
340 } else {
341 fgFitDialog->Show(pad, obj);
342 }
343 return fgFitDialog;
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Constructor of fit editor. 'obj' is the object to be fitted and
348/// 'pad' where it is drawn.
349
351 TGMainFrame(gClient->GetRoot(), 20, 20),
352 fParentPad (0),
353 fFitObject (0),
354 fDim (0),
355 fXaxis (0),
356 fYaxis (0),
357 fZaxis (0),
358 fSumFunc (0),
359 fConvFunc (0),
360 fFuncPars (0),
362{
365
366 TGCompositeFrame *tf = new TGCompositeFrame(this, 350, 26,
368 TGLabel *label = new TGLabel(tf,"Data Set: ");
369 tf->AddFrame(label, new TGLayoutHints(kLHintsNormal, 15, 0, 5, 0));
370
371 fDataSet = new TGComboBox(tf, kFP_DATAS);
373 fDataSet->Resize(264, 20);
374
375 tf->AddFrame(fDataSet, new TGLayoutHints(kLHintsNormal, 13, 0, 5, 0));
376 fDataSet->Associate(this);
377
378 this->AddFrame(tf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX,0,0,5,5));
379
381
382 fTab = new TGTab(this, 10, 10);
384 fTab->SetCleanup(kDeepCleanup);
385 fTab->Associate(this);
386
387 TGHorizontalFrame *cf1 = new TGHorizontalFrame(this, 350, 20, kFixedWidth);
389 fUpdateButton = new TGTextButton(cf1, "&Update", kFP_UPDATE);
390 fUpdateButton->Associate(this);
392 kLHintsExpandX, 0, 20, 2, 2));
393
394
395 fFitButton = new TGTextButton(cf1, "&Fit", kFP_FIT);
396 fFitButton->Associate(this);
398 kLHintsExpandX, 15, -6, 2, 2));
399
400 fResetButton = new TGTextButton(cf1, "&Reset", kFP_RESET);
401 fResetButton->Associate(this);
403 kLHintsExpandX, 11, -2, 2, 2));
404
405 fCloseButton = new TGTextButton(cf1, "&Close", kFP_CLOSE);
406 fCloseButton->Associate(this);
408 kLHintsExpandX, 7, 2, 2, 2));
410 kLHintsRight, 0, 5, 5, 5));
411
412 // Create status bar
413 int parts[] = { 20, 20, 20, 20, 20 };
414 fStatusBar = new TGStatusBar(this, 10, 10);
415 fStatusBar->SetParts(parts, 5);
419
422
423 gROOT->GetListOfCleanups()->Add(this);
424
426 fGeneral->HideFrame(fSliderZParent);
427
428 // do not allow resizing
430 SetWindowName("Fit Panel");
431 SetIconName("Fit Panel");
432 SetClassHints("ROOT", "Fit Panel");
433
439
440 ConnectSlots();
441
443
444 if (!obj) {
445 TList* l = new TList();
446 l->Add(pad);
447 std::vector<TObject*> v;
449 if ( v.size() )
450 obj = v[0];
451 delete l;
452 }
453
454 SetFitObject(pad, obj, kButton1Down);
455
456 // In case we want to make it without a default canvas. This will
457 // be implemented after the 5.21/06 Release. Remember to take out
458 // any reference to the pad/canvas when the fitpanel is shown
459 // and/or built.
460
461 //SetCanvas(0 /*pad->GetCanvas()*/);
462
463 if ( pad ) {
464 SetCanvas(pad->GetCanvas());
465 if ( obj )
466 pad->GetCanvas()->Selected(pad, obj, kButton1Down);
467 }
468
469 UInt_t dw = fClient->GetDisplayWidth();
470 UInt_t cw = 0;
471 UInt_t cx = 0;
472 UInt_t cy = 0;
473 if (pad && pad->GetCanvas() ) {
474 cw = pad->GetCanvas()->GetWindowWidth();
475 cx = (UInt_t)pad->GetCanvas()->GetWindowTopX();
476 cy = (UInt_t)pad->GetCanvas()->GetWindowTopY();
477 }
478
479 Resize(size);
480 MapWindow();
481
482 if (cw + size.fWidth < dw) {
483 Int_t gedx = 0, gedy = 0;
484 gedx = cx+cw+4;
485 gedy = (cy > 20) ? cy-20 : 0;
486 MoveResize(gedx, gedy, size.fWidth, size.fHeight);
487 SetWMPosition(gedx, gedy);
488 }
489
490 gVirtualX->RaiseWindow(GetId());
491
493 SetWMSize(size.fWidth, size.fHeight);
494 SetWMSizeHints(size.fWidth, size.fHeight, size.fWidth, size.fHeight, 0, 0);
495}
496
497////////////////////////////////////////////////////////////////////////////////
498/// Fit editor destructor.
499
501{
503
504 // Disconnect all the slot that were no disconnected in DisconnecSlots
505 fCloseButton ->Disconnect("Clicked()");
506 fDataSet ->Disconnect("Selected(Int_t)");
507 fUpdateButton->Disconnect("Clicked()");
508 TQObject::Disconnect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
509 this, "SetFitObject(TVirtualPad *, TObject *, Int_t)");
510 gROOT->GetListOfCleanups()->Remove(this);
511
512 //Clean up the members that are not automatically cleaned.
513 Cleanup();
514 delete fLayoutNone;
515 delete fLayoutAdd;
516 delete fLayoutConv;
517
518 if (fConvFunc) delete fConvFunc;
519 if (fSumFunc) delete fSumFunc;
520
521 // release memory used by stored functions of previous fits
522 for (auto &entry : fPrevFit)
523 delete entry.second;
524 fPrevFit.clear();
525
526 // release memory used by copies of system functions
527 for (auto func : fSystemFuncs)
528 delete func;
529 fSystemFuncs.clear();
530
531 // Set the singleton reference to null
532 fgFitDialog = 0;
533}
534
535////////////////////////////////////////////////////////////////////////////////
536/// Creates the Frame that contains oll the information about the
537/// function.
538
540{
541 TGGroupFrame *gf1 = new TGGroupFrame(this, "Fit Function", kFitWidth);
542 TGCompositeFrame *tf0 = new TGCompositeFrame(gf1, 350, 26, kHorizontalFrame);
543 TGLabel *label1 = new TGLabel(tf0,"Type:");
544 tf0 -> AddFrame(label1, new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0));
545
546 fTypeFit = new TGComboBox(tf0, kFP_TLIST);
547 fTypeFit -> AddEntry("User Func", kFP_UFUNC);
548 fTypeFit -> AddEntry("Predef-1D", kFP_PRED1D);
549 fTypeFit -> Resize(90, 20);
550 fTypeFit -> Select(kFP_PRED1D, kFALSE);
551
552 TGListBox *lb = fTypeFit->GetListBox();
553 lb->Resize(lb->GetWidth(), 200);
554 tf0->AddFrame(fTypeFit, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
555 fTypeFit->Associate(this);
556
557 fFuncList = new TGComboBox(tf0, kFP_FLIST);
559 fFuncList->Resize(194, 20);
560 fFuncList->Select(kFP_GAUS, kFALSE);
561
562 lb = fFuncList->GetListBox();
563 lb -> Resize(lb->GetWidth(), 500);
564 tf0 -> AddFrame(fFuncList, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
565 fFuncList->Associate(this);
566
568
569 TGCompositeFrame *tf1 = new TGCompositeFrame(gf1, 350, 26, kHorizontalFrame);
570 TGHButtonGroup *bgr = new TGHButtonGroup(tf1, "Operation");
571
572 bgr -> SetRadioButtonExclusive();
573 fNone = new TGRadioButton(bgr, "Nop", kFP_NONE);
574 fAdd = new TGRadioButton(bgr, "Add", kFP_ADD);
575 fNormAdd = new TGRadioButton(bgr, "NormAdd", kFP_NORMADD);
576 fConv = new TGRadioButton(bgr, "Conv", kFP_CONV);
577
578 fNone -> SetToolTipText("No operation defined");
579 fNone -> SetState(kButtonDown, kFALSE);
580 fAdd -> SetToolTipText("Addition");
581 // fAdd -> SetState(kButtonDown, kFALSE);
582 fNormAdd -> SetToolTipText("NormAddition");
583 //fNormAdd -> SetState(kButtonDown, kFALSE);
584 fConv -> SetToolTipText("Convolution");
585 //fConv -> SetState(kButtonDown, kTRUE);
586
587 fLayoutNone = new TGLayoutHints(kLHintsLeft,0 ,5,3,-10);
588 fLayoutAdd = new TGLayoutHints(kLHintsLeft,10,5,3,-10);
589 fLayoutNormAdd = new TGLayoutHints(kLHintsLeft,10,5,3,-10);
590 fLayoutConv = new TGLayoutHints(kLHintsLeft,10,5,3,-10);
591
592 bgr -> SetLayoutHints(fLayoutNone, fNone);
593 bgr -> SetLayoutHints(fLayoutAdd, fAdd);
594 bgr -> SetLayoutHints(fLayoutNormAdd,fNormAdd);
595 bgr -> SetLayoutHints(fLayoutConv, fConv);
596 bgr -> Show();
598
599 tf1 -> AddFrame(bgr, new TGLayoutHints(kLHintsExpandX, 0, 0, 3, 0));
600 gf1 -> AddFrame(tf1, new TGLayoutHints(kLHintsExpandX));
601
602 TGCompositeFrame *tf2 = new TGCompositeFrame(gf1, 350, 26,
604 fEnteredFunc = new TGTextEntry(tf2, new TGTextBuffer(0), kFP_FILE);
605 //fEnteredFunc->SetMaxLength(4000); // use default value (~4000)
606 fEnteredFunc->SetAlignment(kTextLeft);
607 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
608 assert(te);
609 fEnteredFunc->SetText(te->GetTitle());
610 fEnteredFunc->SetToolTipText("Enter file_name/function_name or a function expression");
611 fEnteredFunc->Resize(250,fEnteredFunc->GetDefaultHeight());
614 kLHintsExpandX, 2, 2, 2, 2));
615 gf1->AddFrame(tf2, new TGLayoutHints(kLHintsNormal |
616 kLHintsExpandX, 0, 0, 2, 0));
617
619 TGLabel *label21 = new TGLabel(s1, "Selected: ");
620 s1->AddFrame(label21, new TGLayoutHints(kLHintsNormal |
621 kLHintsCenterY, 2, 2, 2, 0));
623 s1->AddFrame(hlines, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
625
626 TGCompositeFrame *tf4 = new TGCompositeFrame(gf1, 350, 26,
628 TGTextLBEntry *txt = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
629 TString s = txt->GetTitle();
630 fSelLabel = new TGLabel(tf4, s.Sizeof()>30?s(0,30)+"...":s);
632 kLHintsCenterY, 0, 6, 2, 0));
633 Pixel_t color;
634 gClient->GetColorByName("#336666", color);
635 fSelLabel->SetTextColor(color, kFALSE);
636 TGCompositeFrame *tf5 = new TGCompositeFrame(tf4, 120, 20,
638 fSetParam = new TGTextButton(tf5, "Set Parameters...", kFP_PARS);
642 fSetParam->SetToolTipText("Open a dialog for parameter(s) settings");
643 tf4->AddFrame(tf5, new TGLayoutHints(kLHintsRight |
644 kLHintsTop, 5, 0, 2, 2));
645 gf1->AddFrame(tf4, new TGLayoutHints(kLHintsNormal |
646 kLHintsExpandX, 5, 0, 0, 0));
647
648 this->AddFrame(gf1, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
649
650}
651
652////////////////////////////////////////////////////////////////////////////////
653/// Create 'General' tab.
654
656{
657 fTabContainer = fTab->AddTab("General");
661 5, 5, 2, 2));
662
663 // 'options' group frame
664 TGGroupFrame *gf = new TGGroupFrame(fGeneral, "Fit Settings", kFitWidth);
665
666 // 'method' sub-group
668 TGLabel *label4 = new TGLabel(h1, "Method");
669 h1->AddFrame(label4, new TGLayoutHints(kLHintsNormal |
670 kLHintsCenterY, 2, 2, 0, 0));
672 h1->AddFrame(hline1, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
674
678 fMethodList->Select(1, kFALSE);
679 fMethodList->Resize(140, 20);
680 TGListBox *lb = fMethodList->GetListBox();
681 Int_t lbe = lb->GetNumberOfEntries();
682 lb->Resize(lb->GetWidth(), lbe*16);
683 v1->AddFrame(fMethodList, new TGLayoutHints(kLHintsLeft, 0, 0, 2, 5));
684
685 fLinearFit = new TGCheckButton(v1, "Linear fit", kFP_MLINF);
686 fLinearFit->Associate(this);
687 fLinearFit->SetToolTipText("Perform Linear fitter if selected");
688 v1->AddFrame(fLinearFit, new TGLayoutHints(kLHintsNormal, 0, 0, 8, 2));
689
690
692
694 TGCompositeFrame *v21 = new TGCompositeFrame(v2, 120, 20,
696 fUserButton = new TGTextButton(v21, "User-Defined...", kFP_MUSR);
700 fUserButton->SetToolTipText("Open a dialog for entering a user-defined method");
701 fUserButton->SetState(kButtonDisabled);
702 v2->AddFrame(v21, new TGLayoutHints(kLHintsRight | kLHintsTop));
703
705 fEnableRobust = new TGCheckButton(v1h, "Robust:", -1);
706 fEnableRobust->Associate(this); // needed ???
707 fEnableRobust->SetToolTipText("Perform Linear Robust fitter if selected");
708 v1h->AddFrame(fEnableRobust, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
709 fRobustValue = new TGNumberEntry(v1h, 0.95, 5, kFP_RBUST,
714 v2->AddFrame(v1h, new TGLayoutHints(kLHintsNormal, 0, 0, 12, 2));
715 fRobustValue->SetState(kFALSE);
716 fRobustValue->GetNumberEntry()->SetToolTipText("Available only for graphs");
717
718 fNoChi2 = 0;
719 // fNoChi2 = new TGCheckButton(v2, "No Chi-square", kFP_NOCHI);
720 // fNoChi2->Associate(this);
721 // fNoChi2->SetToolTipText("'C'- do not calculate Chi-square (for Linear fitter)");
722 // v2->AddFrame(fNoChi2, new TGLayoutHints(kLHintsNormal, 0, 0, 34, 2));
723
724 h2->AddFrame(v2, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 20, 0, 0, 0));
725 gf->AddFrame(h2, new TGLayoutHints(kLHintsExpandX, 20, 0, 0, 0));
726
727 // 'fit option' sub-group
729 TGLabel *label5 = new TGLabel(h3, "Fit Options");
730 h3->AddFrame(label5, new TGLayoutHints(kLHintsNormal |
731 kLHintsCenterY, 2, 2, 0, 0));
732 TGHorizontal3DLine *hline2 = new TGHorizontal3DLine(h3);
735
738 fIntegral = new TGCheckButton(v3, "Integral", kFP_INTEG);
739 fIntegral->Associate(this);
740 fIntegral->SetToolTipText("'I'- use integral of function instead of value in bin center");
741 v3->AddFrame(fIntegral, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
742
743 fBestErrors = new TGCheckButton(v3, "Best errors", kFP_IMERR);
744 fBestErrors->Associate(this);
745 fBestErrors->SetToolTipText("'E'- better errors estimation using Minos technique");
746 v3->AddFrame(fBestErrors, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
747
748 fAllWeights1 = new TGCheckButton(v3, "All weights = 1", kFP_ALLW1);
749 fAllWeights1->Associate(this);
750 fAllWeights1->SetToolTipText("'W'- all weights=1 for non empty bins; error bars ignored");
751 v3->AddFrame(fAllWeights1, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
752
753 fEmptyBinsWghts1 = new TGCheckButton(v3, "Empty bins, weights=1", kFP_EMPW1);
754 fEmptyBinsWghts1->Associate(this);
755 fEmptyBinsWghts1->SetToolTipText("'WW'- all weights=1 including empty bins; error bars ignored");
756 v3->AddFrame(fEmptyBinsWghts1, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
757
759
761 fUseRange = new TGCheckButton(v4, "Use range", kFP_USERG);
762 fUseRange->Associate(this);
763 fUseRange->SetToolTipText("'R'- fit only data within the specified function range");
764 v4->AddFrame(fUseRange, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
765
766 fImproveResults = new TGCheckButton(v4, "Improve fit results", kFP_IFITR);
767 fImproveResults->Associate(this);
768 fImproveResults->SetToolTipText("'M'- after minimum is found, search for a new one");
769 v4->AddFrame(fImproveResults, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
770
771 fAdd2FuncList = new TGCheckButton(v4, "Add to list", kFP_ADDLS);
772 fAdd2FuncList->Associate(this);
773 fAdd2FuncList->SetToolTipText("'+'- add function to the list without deleting the previous");
774 v4->AddFrame(fAdd2FuncList, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
775
776 fUseGradient = new TGCheckButton(v4, "Use Gradient", kFP_ADDLS);
777 fUseGradient->Associate(this);
778 fUseGradient->SetToolTipText("'G'- Use the gradient as an aid for the fitting");
779 v4->AddFrame(fUseGradient, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
780
781 h->AddFrame(v4, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 20, 0, 0, 0));
782 gf->AddFrame(h, new TGLayoutHints(kLHintsExpandX, 20, 0, 0, 0));
783
784 // 'draw option' sub-group
786 TGLabel *label6 = new TGLabel(h5, "Draw Options");
787 h5->AddFrame(label6, new TGLayoutHints(kLHintsNormal |
788 kLHintsCenterY, 2, 2, 2, 2));
789 TGHorizontal3DLine *hline3 = new TGHorizontal3DLine(h5);
792
794 TGVerticalFrame *v5 = new TGVerticalFrame(h6);
795
796 fDrawSame = new TGCheckButton(v5, "SAME", kFP_DSAME);
797 fDrawSame->Associate(this);
798 fDrawSame->SetToolTipText("Superimpose on previous picture in the same pad");
799 v5->AddFrame(fDrawSame, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
800
801 fNoDrawing = new TGCheckButton(v5, "No drawing", kFP_DNONE);
802 fNoDrawing->Associate(this);
803 fNoDrawing->SetToolTipText("'0'- do not draw function graphics");
804 v5->AddFrame(fNoDrawing, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
805
806 fNoStoreDrawing = new TGCheckButton(v5, "Do not store/draw", kFP_DNOST);
807 fNoStoreDrawing->Associate(this);
808 fNoStoreDrawing->SetToolTipText("'N'- do not store the function, do not draw it");
810
812
813 TGVerticalFrame *v6 = new TGVerticalFrame(h6);
814 TGCompositeFrame *v61 = new TGCompositeFrame(v6, 120, 20,
816 fDrawAdvanced = new TGTextButton(v61, "&Advanced...", kFP_DADVB);
820 fDrawAdvanced->SetToolTipText("Open a dialog for advanced draw options");
822
824 0, 0, (4+fDrawSame->GetHeight())*2, 0));
825
827 gf->AddFrame(h6, new TGLayoutHints(kLHintsExpandX, 20, 0, 2, 0));
828
829 fGeneral->AddFrame(gf, new TGLayoutHints(kLHintsExpandX |
830 kLHintsExpandY, 5, 5, 0, 0));
831 // sliderX
833 TGLabel *label8 = new TGLabel(fSliderXParent, "X");
834 fSliderXParent->AddFrame(label8, new TGLayoutHints(kLHintsLeft |
835 kLHintsCenterY, 0, 5, 0, 0));
836
842
844 fSliderX->SetScale(5);
846
847
853 fGeneral->AddFrame(fSliderXParent, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
854
855 // sliderY
857 TGLabel *label9 = new TGLabel(fSliderYParent, "Y");
858 fSliderYParent->AddFrame(label9, new TGLayoutHints(kLHintsLeft |
859 kLHintsCenterY, 0, 5, 0, 0));
860
866
868 fSliderY->SetScale(5);
870
876 fGeneral->AddFrame(fSliderYParent, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
877
878 // sliderZ
880 TGLabel *label10 = new TGLabel(fSliderZParent, "Z:");
881 fSliderZParent->AddFrame(label10, new TGLayoutHints(kLHintsLeft |
882 kLHintsCenterY, 0, 5, 0, 0));
884 fSliderZ->SetScale(5);
887 fGeneral->AddFrame(fSliderZParent, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
888}
889
890
891////////////////////////////////////////////////////////////////////////////////
892/// Create 'Minimization' tab.
893
895{
896 fTabContainer = fTab->AddTab("Minimization");
900 5, 5, 2, 2));
901 MakeTitle(fMinimization, "Library");
902
904 fLibMinuit = new TGRadioButton(hl, "Minuit", kFP_LMIN);
905 fLibMinuit->Associate(this);
906 fLibMinuit->SetToolTipText("Use minimization from libMinuit (default)");
907 hl->AddFrame(fLibMinuit, new TGLayoutHints(kLHintsNormal, 40, 0, 0, 1));
908 fStatusBar->SetText("LIB Minuit",1);
909
910 fLibMinuit2 = new TGRadioButton(hl, "Minuit2", kFP_LMIN2);
911 fLibMinuit2->Associate(this);
912 fLibMinuit2->SetToolTipText("New C++ version of Minuit");
913 hl->AddFrame(fLibMinuit2, new TGLayoutHints(kLHintsNormal, 35, 0, 0, 1));
914
915 fLibFumili = new TGRadioButton(hl, "Fumili", kFP_LFUM);
916 fLibFumili->Associate(this);
917 fLibFumili->SetToolTipText("Use minimization from libFumili");
918 hl->AddFrame(fLibFumili, new TGLayoutHints(kLHintsNormal, 30, 0, 0, 1));
919 fMinimization->AddFrame(hl, new TGLayoutHints(kLHintsExpandX, 20, 0, 5, 1));
920
922
923 fLibGSL = new TGRadioButton(hl2, "GSL", kFP_LGSL);
924 #ifdef R__HAS_MATHMORE
925 fLibGSL->Associate(this);
926 fLibGSL->SetToolTipText("Use minimization from libGSL");
927 #else
928 fLibGSL->SetState(kButtonDisabled);
929 fLibGSL->SetToolTipText("Needs GSL to be compiled");
930 #endif
931 hl2->AddFrame(fLibGSL, new TGLayoutHints(kLHintsNormal, 40, 0, 0, 1));
932
933 fLibGenetics = new TGRadioButton(hl2, "Genetics", kFP_LGAS);
934 if (gPluginMgr->FindHandler("ROOT::Math::Minimizer","Genetic") ||
935 gPluginMgr->FindHandler("ROOT::Math::Minimizer","GAlibMin") )
936 {
937 fLibGenetics->Associate(this);
938 fLibGenetics->SetToolTipText("Different GAs implementations");
939 } else {
940 fLibGenetics->SetState(kButtonDisabled);
941 fLibGenetics->SetToolTipText("Needs any of the genetic"
942 "minimizers to be compiled");
943 }
944 hl2->AddFrame(fLibGenetics, new TGLayoutHints(kLHintsNormal, 45, 0, 0, 1));
945
946 fMinimization->AddFrame(hl2, new TGLayoutHints(kLHintsExpandX, 20, 0, 5, 1));
947
948 MakeTitle(fMinimization, "Method");
949
952 fMinMethodList->Resize(290, 20);
954
955 TGListBox *lb = fMinMethodList->GetListBox();
956 lb->Resize(lb->GetWidth(), 500);
957 fMinMethodList->Associate(this);
958
960 fMinimization->AddFrame(hm0, new TGLayoutHints(kLHintsExpandX, 60, 0, 5, 1));
961
962 // Set the status to the default minimization options!
964 fLibFumili->SetState(kButtonDown);
965 } else if ( ROOT::Math::MinimizerOptions::DefaultMinimizerType() == "Minuit" ) {
966 fLibMinuit->SetState(kButtonDown);
967 } else {
968 fLibMinuit2->SetState(kButtonDown);
969 }
971
972 MakeTitle(fMinimization, "Settings");
973 TGLabel *hslabel1 = new TGLabel(fMinimization,"Use ENTER key to validate a new value or click");
974 fMinimization->AddFrame(hslabel1, new TGLayoutHints(kLHintsNormal, 61, 0, 5, 1));
975 TGLabel *hslabel2 = new TGLabel(fMinimization,"on Reset button to set the defaults.");
976 fMinimization->AddFrame(hslabel2, new TGLayoutHints(kLHintsNormal, 61, 0, 1, 10));
977
979
980 TGVerticalFrame *hsv1 = new TGVerticalFrame(hs, 180, 10, kFixedWidth);
981 TGLabel *errlabel = new TGLabel(hsv1,"Error definition (default = 1): ");
982 hsv1->AddFrame(errlabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
983 1, 1, 5, 7));
984 TGLabel *tollabel = new TGLabel(hsv1,"Max tolerance (precision): ");
985 hsv1->AddFrame(tollabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
986 1, 1, 5, 7));
987 TGLabel *itrlabel = new TGLabel(hsv1,"Max number of iterations: ");
988 hsv1->AddFrame(itrlabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
989 1, 1, 5, 5));
990 hs->AddFrame(hsv1, new TGLayoutHints(kLHintsNormal, 60, 0, 0, 0));
991
992 TGVerticalFrame *hsv2 = new TGVerticalFrame(hs, 90,10, kFixedWidth);
998 1, 1, 0, 3));
1005 1, 1, 3, 3));
1006 fIterations = new TGNumberEntryField(hsv2, kFP_MITR, 5000,
1012 1, 1, 3, 3));
1013 hs->AddFrame(hsv2, new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
1014 fMinimization->AddFrame(hs, new TGLayoutHints(kLHintsExpandX, 0, 0, 1, 1));
1016
1017 MakeTitle(fMinimization, "Print Options");
1018
1020 fOptDefault = new TGRadioButton(h8, "Default", kFP_PDEF);
1021 fOptDefault->Associate(this);
1022 fOptDefault->SetToolTipText("Default is between Verbose and Quiet");
1023 h8->AddFrame(fOptDefault, new TGLayoutHints(kLHintsNormal, 40, 0, 0, 1));
1024 fOptDefault->SetState(kButtonDown);
1025 fStatusBar->SetText("Prn: DEF",4);
1026
1027 fOptVerbose = new TGRadioButton(h8, "Verbose", kFP_PVER);
1028 fOptVerbose->Associate(this);
1029 fOptVerbose->SetToolTipText("'V'- print results after each iteration");
1030 h8->AddFrame(fOptVerbose, new TGLayoutHints(kLHintsNormal, 30, 0, 0, 1));
1031
1032 fOptQuiet = new TGRadioButton(h8, "Quiet", kFP_PQET);
1033 fOptQuiet->Associate(this);
1034 fOptQuiet->SetToolTipText("'Q'- no print");
1035 h8->AddFrame(fOptQuiet, new TGLayoutHints(kLHintsNormal, 25, 0, 0, 1));
1036
1037 fMinimization->AddFrame(h8, new TGLayoutHints(kLHintsExpandX, 20, 0, 5, 1));
1038
1039}
1040
1041////////////////////////////////////////////////////////////////////////////////
1042/// Connect GUI signals to fit panel slots.
1043
1045{
1046 // list of data sets to fit
1047 fDataSet -> Connect("Selected(Int_t)", "TFitEditor", this, "DoDataSet(Int_t)");
1048 // list of predefined functions
1049 fTypeFit -> Connect("Selected(Int_t)", "TFitEditor", this, "FillFunctionList(Int_t)");
1050 // list of predefined functions
1051 fFuncList -> Connect("Selected(Int_t)", "TFitEditor", this, "DoFunction(Int_t)");
1052 // entered formula or function name
1053 fEnteredFunc -> Connect("ReturnPressed()", "TFitEditor", this, "DoEnteredFunction()");
1054 // set parameters dialog
1055 fSetParam -> Connect("Clicked()", "TFitEditor", this, "DoSetParameters()");
1056 // allowed function operations
1057 fAdd -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoAddition(Bool_t)");
1058 //fNormAdd -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoNormAddition(Bool_t)");
1059 //fConv -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoConvolution(Bool_t)");
1060 // fit options
1061 fAllWeights1 -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoAllWeights1()");
1062 fUseRange -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoUseFuncRange()");
1063 fEmptyBinsWghts1 -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoEmptyBinsAllWeights1()");
1064 // linear fit
1065 fLinearFit -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoLinearFit()");
1066 fEnableRobust -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoRobustFit()");
1067 //fNoChi2->Connect("Toggled(Bool_t)","TFitEditor",this,"DoNoChi2()");
1068 // draw options
1069 fNoStoreDrawing -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoNoStoreDrawing()");
1070 // fit, reset, close buttons
1071 fUpdateButton -> Connect("Clicked()", "TFitEditor", this, "DoUpdate()");
1072 fFitButton -> Connect("Clicked()", "TFitEditor", this, "DoFit()");
1073 fResetButton -> Connect("Clicked()", "TFitEditor", this, "DoReset()");
1074 fCloseButton -> Connect("Clicked()", "TFitEditor", this, "DoClose()");
1075 // user method button
1076 fUserButton -> Connect("Clicked()", "TFitEditor", this, "DoUserDialog()");
1077 // advanced draw options
1078 fDrawAdvanced -> Connect("Clicked()", "TFitEditor", this, "DoAdvancedOptions()");
1079
1080 if (fType != kObjectTree)
1081 {
1082 fSliderX -> Connect("PositionChanged()","TFitEditor",this, "DoSliderXMoved()");
1083 fSliderXMax -> Connect("ValueSet(Long_t)", "TFitEditor",this, "DoNumericSliderXChanged()");
1084 fSliderXMin -> Connect("ValueSet(Long_t)", "TFitEditor",this, "DoNumericSliderXChanged()");
1085 }
1086 if (fDim > 1)
1087 {
1088 fSliderY -> Connect("PositionChanged()","TFitEditor",this, "DoSliderYMoved()");
1089 fSliderYMax -> Connect("ValueSet(Long_t)", "TFitEditor",this, "DoNumericSliderYChanged()");
1090 fSliderYMin -> Connect("ValueSet(Long_t)", "TFitEditor",this, "DoNumericSliderYChanged()");
1091 }
1092 if (fDim > 2)
1093 fSliderZ -> Connect("PositionChanged()","TFitEditor",this, "DoSliderZMoved()");
1094
1095 if ( fParentPad )
1096 fParentPad -> Connect("RangeAxisChanged()","TFitEditor",this, "UpdateGUI()");
1097 // 'Minimization' tab
1098 // library
1099 fLibMinuit -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoLibrary(Bool_t)");
1100 fLibMinuit2 -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoLibrary(Bool_t)");
1101 fLibFumili -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoLibrary(Bool_t)");
1102 fLibGSL -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoLibrary(Bool_t)");
1103 fLibGenetics -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoLibrary(Bool_t)");
1104
1105 // minimization method
1106 fMinMethodList -> Connect("Selected(Int_t)", "TFitEditor", this, "DoMinMethod(Int_t)");
1107 // fitter settings
1108 fIterations -> Connect("ReturnPressed()", "TFitEditor", this, "DoMaxIterations()");
1109 // print options
1110 fOptDefault -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoPrintOpt(Bool_t)");
1111 fOptVerbose -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoPrintOpt(Bool_t)");
1112 fOptQuiet -> Connect("Toggled(Bool_t)", "TFitEditor", this, "DoPrintOpt(Bool_t)");
1113
1114}
1115
1116////////////////////////////////////////////////////////////////////////////////
1117/// Disconnect GUI signals from fit panel slots.
1118
1120{
1121 Disconnect("CloseWindow()");
1122
1123 fFuncList -> Disconnect("Selected(Int_t)");
1124 fEnteredFunc -> Disconnect("ReturnPressed()");
1125 fSetParam -> Disconnect("Clicked()");
1126 fAdd -> Disconnect("Toggled(Bool_t)");
1127 // fNormAdd -> Disconnect("Toggled(Bool_t)");
1128 // fConv -> Disconnect("Toggled(Bool_t)");
1129
1130 // fit options
1131 fAllWeights1 -> Disconnect("Toggled(Bool_t)");
1132 fEmptyBinsWghts1 -> Disconnect("Toggled(Bool_t)");
1133
1134 // linear fit
1135 fLinearFit -> Disconnect("Toggled(Bool_t)");
1136 fEnableRobust -> Disconnect("Toggled(Bool_t)");
1137 //fNoChi2->Disconnect("Toggled(Bool_t)");
1138
1139 // draw options
1140 fNoStoreDrawing -> Disconnect("Toggled(Bool_t)");
1141
1142 // fit, reset, close buttons
1143 fFitButton -> Disconnect("Clicked()");
1144 fResetButton -> Disconnect("Clicked()");
1145
1146 // other methods
1147 fUserButton -> Disconnect("Clicked()");
1148 fDrawAdvanced -> Disconnect("Clicked()");
1149
1150 if (fType != kObjectTree)
1151 {
1152 fSliderX -> Disconnect("PositionChanged()");
1153 fSliderXMax -> Disconnect("ValueChanged(Long_t)");
1154 fSliderXMin -> Disconnect("ValueChanged(Long_t)");
1155 }
1156 if (fDim > 1)
1157 {
1158 fSliderY -> Disconnect("PositionChanged()");
1159 fSliderYMax -> Disconnect("ValueChanged(Long_t)");
1160 fSliderYMin -> Disconnect("ValueChanged(Long_t)");
1161 }
1162 if (fDim > 2)
1163 fSliderZ -> Disconnect("PositionChanged()");
1164 // slots related to 'Minimization' tab
1165 fLibMinuit -> Disconnect("Toggled(Bool_t)");
1166 fLibMinuit2 -> Disconnect("Toggled(Bool_t)");
1167 fLibFumili -> Disconnect("Toggled(Bool_t)");
1168 fLibGSL -> Disconnect("Toggled(Bool_t)");
1169 fLibGenetics -> Disconnect("Toggled(Bool_t)");
1170 // minimization method
1171 fMinMethodList -> Disconnect("Selected(Int_t)");
1172 // fitter settings
1173 fIterations -> Disconnect("ReturnPressed()");
1174 // print options
1175 fOptDefault -> Disconnect("Toggled(Bool_t)");
1176 fOptVerbose -> Disconnect("Toggled(Bool_t)");
1177 fOptQuiet -> Disconnect("Toggled(Bool_t)");
1178
1179}
1180
1181////////////////////////////////////////////////////////////////////////////////
1182/// Connect to another canvas.
1183
1185{
1186 // The next line is commented because it is stablishing a
1187 // connection with the particular canvas, while right the following
1188 // line will connect all the canvas in a general way.
1189
1190 // It would also make the fitpanel crash if there is no object
1191 // defined to be fitted in the construction (as a side effect of
1192 // it).
1193
1194// newcan->Connect("Selected(TVirtualPad*,TObject*,Int_t)", "TFitEditor",
1195// this, "SetFitObject(TVirtualPad *, TObject *, Int_t)");
1196
1197 TQObject::Connect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
1198 "TFitEditor",this,
1199 "SetFitObject(TVirtualPad *, TObject *, Int_t)");
1200 TQObject::Connect("TCanvas", "Closed()", "TFitEditor", this, "DoNoSelection()");
1201}
1202
1203////////////////////////////////////////////////////////////////////////////////
1204/// Hide the fit panel and set it to non-active state.
1205
1207{
1208 if (fgFitDialog) {
1209 fgFitDialog->UnmapWindow();
1210 }
1211 if (fParentPad) {
1212 fParentPad->Disconnect("RangeAxisChanged()");
1213 DoReset();
1214 TQObject::Disconnect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
1215 this, "SetFitObject(TVirtualPad *, TObject *, Int_t)");
1216 }
1217 fParentPad = 0;
1218 fFitObject = 0;
1219 gROOT->GetListOfCleanups()->Remove(this);
1220}
1221
1222////////////////////////////////////////////////////////////////////////////////
1223/// Show the fit panel (possible only via context menu).
1224
1226{
1227 if (!gROOT->GetListOfCleanups()->FindObject(this))
1228 gROOT->GetListOfCleanups()->Add(this);
1229
1230 if (!fgFitDialog->IsMapped()) {
1231 fgFitDialog->MapWindow();
1232 gVirtualX->RaiseWindow(GetId());
1233 }
1234 fParentPad = static_cast<TPad*>(pad);
1235 SetCanvas(pad->GetCanvas());
1236 SetFitObject(pad, obj, kButton1Down);
1237}
1238
1239////////////////////////////////////////////////////////////////////////////////
1240/// Close fit panel window.
1241
1243{
1244 Hide();
1245}
1246
1247//______________________________________________________________________________
1248// TFitEditor *&TFitEditor::GetFP()
1249// {
1250// // Static: return main fit panel
1251// return fgFitDialog;
1252// }
1253
1254////////////////////////////////////////////////////////////////////////////////
1255/// Called to delete the fit panel.
1256
1258{
1259 if (HasConnection("DoNoSelection()"))
1260 TQObject::Disconnect("TCanvas", "Closed()");
1261 delete fgFitDialog;
1262 fgFitDialog = 0;
1263}
1264
1265////////////////////////////////////////////////////////////////////////////////
1266/// Set the fit panel GUI according to the selected object.
1267
1269{
1270 if (!fFitObject) return;
1271
1272 DrawSelection(true);
1273
1274 if ( fType == kObjectTree )
1275 // Don't do anything with the sliders, as they work with TAxis
1276 // that are not defined for the TTree
1277 return;
1278
1279 // sliders
1280 if (fType != kObjectTree) { // This is as fDim > 0
1281 TH1* hist = 0;
1282 switch (fType) {
1283 case kObjectHisto:
1284 hist = (TH1*)fFitObject;
1285 break;
1286
1287 case kObjectGraph:
1288 hist = ((TGraph*)fFitObject)->GetHistogram();
1289 break;
1290
1291 case kObjectMultiGraph:
1292 hist = ((TMultiGraph*)fFitObject)->GetHistogram();
1293 break;
1294
1295 case kObjectGraph2D:
1296 hist = ((TGraph2D*)fFitObject)->GetHistogram("empty");
1297 break;
1298
1299 case kObjectHStack:
1300 hist = (TH1 *)((THStack *)fFitObject)->GetHists()->First();
1301
1302 case kObjectTree:
1303 default:
1304 break;
1305 }
1306
1307
1308 if (!hist) {
1309 Error("UpdateGUI","No hist is present - this should not happen, please report."
1310 "The FitPanel might be in an inconsistent state");
1311 //assert(hist);
1312 return;
1313 }
1314
1315 fSliderX->Disconnect("PositionChanged()");
1316 fSliderXMin->Disconnect("ValueChanged()");
1317 fSliderXMax->Disconnect("ValueChanged()");
1318
1319 if (!fSliderXParent->IsMapped())
1320 fSliderXParent->MapWindow();
1321
1322 fXaxis = hist->GetXaxis();
1323 fYaxis = hist->GetYaxis();
1324 fZaxis = hist->GetZaxis();
1325 Int_t ixrange = fXaxis->GetNbins();
1326 Int_t ixmin = fXaxis->GetFirst();
1327 Int_t ixmax = fXaxis->GetLast();
1328
1329 if (ixmin > 1 || ixmax < ixrange) {
1330 fSliderX->SetRange(ixmin,ixmax);
1331 fSliderX->SetPosition(ixmin, ixmax);
1332 } else {
1333 fSliderX->SetRange(1,ixrange);
1334 fSliderX->SetPosition(ixmin,ixmax);
1335 }
1336
1337 fSliderX->SetScale(5);
1338
1340 fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ),
1341 fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
1342 fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ));
1344 fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ),
1345 fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
1346 fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
1347
1348 fSliderX->Connect("PositionChanged()","TFitEditor",this, "DoSliderXMoved()");
1349 fSliderXMax->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderXChanged()");
1350 fSliderXMin->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderXChanged()");
1351 }
1352
1353 if (fDim > 1) {
1354 fSliderY->Disconnect("PositionChanged()");
1355 fSliderYMin->Disconnect("ValueChanged()");
1356 fSliderYMax->Disconnect("ValueChanged()");
1357
1358 if (!fSliderYParent->IsMapped())
1359 fSliderYParent->MapWindow();
1360 if (fSliderZParent->IsMapped())
1361 fSliderZParent->UnmapWindow();
1362
1363 Int_t iymin = 0, iymax = 0, iyrange = 0;
1364 switch (fType) {
1365 case kObjectHisto:
1366 case kObjectGraph2D:
1367 case kObjectHStack:
1368 iyrange = fYaxis->GetNbins();
1369 iymin = fYaxis->GetFirst();
1370 iymax = fYaxis->GetLast();
1371 break;
1372
1373 case kObjectGraph:
1374 case kObjectMultiGraph:
1375 case kObjectTree:
1376 default:
1377 //not implemented
1378 break;
1379 }
1380
1381 if (iymin > 1 || iymax < iyrange) {
1382 fSliderY->SetRange(iymin,iymax);
1383 fSliderY->SetPosition(iymin, iymax);
1384 } else {
1385 fSliderY->SetRange(1,iyrange);
1386 fSliderY->SetPosition(iymin,iymax);
1387 }
1388
1389 fSliderY->SetScale(5);
1390
1392 fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ),
1393 fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
1394 fSliderYMin->SetNumber(fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ));
1396 fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ),
1397 fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
1398 fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
1399
1400 fSliderY->Connect("PositionChanged()","TFitEditor",this, "DoSliderYMoved()");
1401 fSliderYMax->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderYChanged()");
1402 fSliderYMin->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderYChanged()");
1403 }
1404
1405
1406 if (fDim > 2) {
1407 fSliderZ->Disconnect("PositionChanged()");
1408
1409 if (!fSliderZParent->IsMapped())
1410 fSliderZParent->MapWindow();
1411
1412 Int_t izmin = 0, izmax = 0, izrange = 0;
1413 switch (fType) {
1414 case kObjectHStack:
1415 case kObjectHisto:
1416 izrange = fZaxis->GetNbins();
1417 izmin = fZaxis->GetFirst();
1418 izmax = fZaxis->GetLast();
1419 break;
1420
1421 case kObjectGraph:
1422 case kObjectGraph2D:
1423 case kObjectMultiGraph:
1424 case kObjectTree:
1425 default:
1426 //not implemented
1427 break;
1428 }
1429
1430 if (izmin > 1 || izmax < izrange) {
1431 fSliderZ->SetRange(izmin,izmax);
1432 fSliderZ->SetPosition(izmin, izmax);
1433 } else {
1434 fSliderZ->SetRange(1,izrange);
1435 fSliderZ->SetPosition(izmin,izmax);
1436 }
1437
1438 fSliderZ->SetScale(5);
1439 fSliderZ->Connect("PositionChanged()","TFitEditor",this, "DoSliderZMoved()");
1440 }
1441}
1442
1443////////////////////////////////////////////////////////////////////////////////
1444/// Slot called when the user clicks on an object inside a canvas.
1445/// Updates pointers to the parent pad and the selected object
1446/// for fitting (if suitable).
1447
1449{
1450 if (event != kButton1Down) return;
1451
1452 if ( !obj ) {
1453 DoNoSelection();
1454 return;
1455 }
1456
1457 // is obj suitable for fitting?
1458 if (!SetObjectType(obj)) return;
1459
1460 fParentPad = pad;
1461 fFitObject = obj;
1462 ShowObjectName(obj);
1463 UpdateGUI();
1464
1465 ConnectSlots();
1466
1467 TF1* fitFunc = HasFitFunction();
1468
1469 if (fitFunc)
1470 {
1471 //fFuncPars = FuncParams_t( fitFunc->GetNpar() );
1472 GetParameters(fFuncPars, fitFunc);
1473
1474 TString tmpStr = fitFunc->GetExpFormula();
1475 TGLBEntry *en = 0;
1476 // If the function comes from a C raw function.
1477 if ( tmpStr.Length() == 0 )
1478 {
1479 // Show the name of the function
1480 fEnteredFunc->SetText(fitFunc->GetName());
1481 en= fFuncList->FindEntry(fitFunc->GetName());
1482 // Don't allow edition!
1484 }
1485 // otherwise, it's got a formula
1486 else
1487 {
1488 // Show the formula
1489 fEnteredFunc->SetText(fitFunc->GetExpFormula().Data());
1490 en= fFuncList->FindEntry(fitFunc->GetExpFormula().Data());
1492 }
1493 // Select the proper entry in the function list
1494 if (en) fFuncList->Select(en->EntryId());
1495 }
1496 else
1497 { // if there is no fit function in the object
1498 // Use the selected function in fFuncList
1499 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
1500 // Add the text to fEnteredFunc
1501 if (te && fNone->GetState() == kButtonDown)
1502 fEnteredFunc->SetText(te->GetTitle());
1503 else if (te && fAdd->GetState() == kButtonDown)
1504 {
1505 TString tmpStr = fEnteredFunc->GetText();
1506 tmpStr += '+';
1507 tmpStr += te->GetTitle();
1508 fEnteredFunc->SetText(tmpStr);
1509 }
1510 else if (te && fNormAdd->GetState() == kButtonDown)
1511 {
1512 TString tmpStr = fEnteredFunc->GetText();
1513 tmpStr += '+';
1514 tmpStr += te -> GetTitle();
1515 fEnteredFunc -> SetText(tmpStr);
1516 }
1517 else if (te && fConv->GetState() == kButtonDown)
1518 {
1519 TString tmpStr = fEnteredFunc->GetText();
1520 tmpStr += '*';
1521 tmpStr +=te->GetTitle();
1522 fEnteredFunc->SetText(tmpStr);
1523 }
1524 else if ( !te )
1525 // If there is no space, an error message is shown:
1526 // Error in <TString::AssertElement>: out of bounds: i = -1, Length = 0
1527 // If there is no function selected, then put nothing.
1528 fEnteredFunc->SetText(" ");
1529 }
1530 fEnteredFunc->SelectAll();
1531
1532
1533 // Update the information about the selected object.
1534 if (fSetParam->GetState() == kButtonDisabled)
1535 fSetParam->SetEnabled(kTRUE);
1536 if (fFitButton->GetState() == kButtonDisabled)
1537 fFitButton->SetEnabled(kTRUE);
1538 if (fResetButton->GetState() == kButtonDisabled)
1539 fResetButton->SetEnabled(kTRUE);
1540 DoLinearFit();
1541}
1542
1543////////////////////////////////////////////////////////////////////////////////
1544/// Slot called when users close a TCanvas or when the user select
1545/// no object.
1546
1548{
1549 if (gROOT->GetListOfCanvases()->IsEmpty()) {
1550 Terminate();
1551 return;
1552 }
1553
1554 // Minimize user interaction until an object is selected
1556 fParentPad = 0;
1557 fFitObject = 0;
1558 fStatusBar->SetText("No selection",0);
1559 fDataSet->Select(kFP_NOSEL, kFALSE);
1560 Layout();
1561
1562 fSetParam->SetEnabled(kFALSE);
1563 fFitButton->SetEnabled(kFALSE);
1564 fResetButton->SetEnabled(kFALSE);
1565 fDrawAdvanced->SetState(kButtonDisabled);
1566}
1567
1568////////////////////////////////////////////////////////////////////////////////
1569/// When obj is deleted, clear fFitObject if fFitObject = obj.
1570
1572{
1573 if (obj == fFitObject) {
1574 fFitObject = 0;
1576 fStatusBar->SetText("No selection",0);
1577 fDataSet->Select(kFP_NOSEL, kFALSE);
1578 Layout();
1579
1580 fFitButton->SetEnabled(kFALSE);
1581 fResetButton->SetEnabled(kFALSE);
1582 fSetParam->SetEnabled(kFALSE);
1583
1584 TQObject::Connect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
1585 "TFitEditor",this,
1586 "SetFitObject(TVirtualPad *, TObject *, Int_t)");
1587 TQObject::Connect("TCanvas", "Closed()", "TFitEditor", this,
1588 "DoNoSelection()");
1589
1590 DoUpdate();
1591 return;
1592 }
1593 if (obj == fParentPad) {
1594 fFitObject = 0;
1595 fParentPad = 0;
1597 fStatusBar->SetText("No selection",0);
1598 fDataSet->Select(kFP_NOSEL, kFALSE);
1599 Layout();
1600
1601 fFitButton->SetEnabled(kFALSE);
1602 fResetButton->SetEnabled(kFALSE);
1603 fSetParam->SetEnabled(kFALSE);
1604 }
1605}
1606
1607////////////////////////////////////////////////////////////////////////////////
1608/// Fills the list of functions depending on the type of fit
1609/// selected.
1610
1612{
1613 fFuncList->RemoveAll();
1614 // Case when the user has selected predefined functions in 1D.
1615 if ( fTypeFit->GetSelected() == kFP_PRED1D && fDim <= 1 ) {
1616 // Fill function list combo box.
1617 fFuncList->AddEntry("gaus" , kFP_GAUS);
1618 fFuncList->AddEntry("gausn", kFP_GAUSN);
1619 fFuncList->AddEntry("expo", kFP_EXPO);
1620 fFuncList->AddEntry("landau", kFP_LAND);
1621 fFuncList->AddEntry("landaun",kFP_LANDN);
1622 fFuncList->AddEntry("pol0", kFP_POL0);
1623 fFuncList->AddEntry("pol1", kFP_POL1);
1624 fFuncList->AddEntry("pol2", kFP_POL2);
1625 fFuncList->AddEntry("pol3", kFP_POL3);
1626 fFuncList->AddEntry("pol4", kFP_POL4);
1627 fFuncList->AddEntry("pol5", kFP_POL5);
1628 fFuncList->AddEntry("pol6", kFP_POL6);
1629 fFuncList->AddEntry("pol7", kFP_POL7);
1630 fFuncList->AddEntry("pol8", kFP_POL8);
1631 fFuncList->AddEntry("pol9", kFP_POL9);
1632 fFuncList->AddEntry("cheb0", kFP_CHEB0);
1633 fFuncList->AddEntry("cheb1", kFP_CHEB1);
1634 fFuncList->AddEntry("cheb2", kFP_CHEB2);
1635 fFuncList->AddEntry("cheb3", kFP_CHEB3);
1636 fFuncList->AddEntry("cheb4", kFP_CHEB4);
1637 fFuncList->AddEntry("cheb5", kFP_CHEB5);
1638 fFuncList->AddEntry("cheb6", kFP_CHEB6);
1639 fFuncList->AddEntry("cheb7", kFP_CHEB7);
1640 fFuncList->AddEntry("cheb8", kFP_CHEB8);
1641 fFuncList->AddEntry("cheb9", kFP_CHEB9);
1642 fFuncList->AddEntry("user", kFP_USER);
1643
1644 // Need to be setted this way, otherwise when the functions
1645 // are removed, the list doesn't show them.
1646 TGListBox *lb = fFuncList->GetListBox();
1647 lb->Resize(lb->GetWidth(), 200);
1648
1649 // Select Gaus1D by default
1650 fFuncList->Select(kFP_GAUS);
1651
1652 }
1653 // Case for predefined 2D functions
1654 else if ( fTypeFit->GetSelected() == kFP_PRED2D && fDim == 2 ) {
1655 fFuncList->AddEntry("xygaus", kFP_XYGAUS);
1656 fFuncList->AddEntry("bigaus", kFP_BIGAUS);
1657 fFuncList->AddEntry("xyexpo", kFP_XYEXP);
1658 fFuncList->AddEntry("xylandau", kFP_XYLAN);
1659 fFuncList->AddEntry("xylandaun", kFP_XYLANN);
1660
1661 // Need to be setted this way, otherwise when the functions
1662 // are removed, the list doesn't show them.x
1663 TGListBox *lb = fFuncList->GetListBox();
1664 lb->Resize(lb->GetWidth(), 200);
1665
1666 // Select Gaus2D by default
1667 fFuncList->Select(kFP_XYGAUS);
1668 } else if (fTypeFit->GetSelected() == kFP_PRED3D && fDim == 3) {
1669 fFuncList->AddEntry("xyzgaus", kFP_XYZGAUS);
1670
1671 // Need to be setted this way, otherwise when the functions
1672 // are removed, the list doesn't show them.x
1673 TGListBox *lb = fFuncList->GetListBox();
1674 lb->Resize(lb->GetWidth(), 200);
1675
1676 // Select Gaus3D by default
1677 fFuncList->Select(kFP_XYZGAUS);
1678 }
1679 // Case for user defined functions. References to these functions
1680 // are kept by the fitpanel, so the information is gathered from
1681 // there.
1682 else if (fTypeFit->GetSelected() == kFP_UFUNC) {
1683 Int_t newid = kFP_ALTFUNC;
1684
1685 // Add system functions
1686 for (auto f : fSystemFuncs) {
1687 // Don't include system functions that has been previously
1688 // used to fit, as those are included under the kFP_PREVFIT
1689 // section.
1690 if ( strncmp(f->GetName(), "PrevFit", 7) != 0 ) {
1691 // If the dimension of the object coincides with the
1692 // dimension of the function, then include the function in
1693 // the list. It will also include de function if the
1694 // dimension of the object is 0 (i.e. a multivariable
1695 // TTree) as it is currently imposible to know how many
1696 // dimensions a TF1 coming from a C raw function has.
1697 if ( f->GetNdim() == fDim || fDim == 0) {
1698 fFuncList->AddEntry(f->GetName(), newid++);
1699 }
1700 }
1701 }
1702
1703 // If no function was added
1704 if ( newid != kFP_ALTFUNC )
1705 fFuncList->Select(newid-1);
1706 else if( fDim == 1 ) {
1707 // Select predefined 1D functions for 1D objects
1708 fTypeFit->Select(kFP_PRED1D, kTRUE);
1709 } else if( fDim == 2 ) {
1710 // Select predefined 2D functions for 2D objects
1711 fTypeFit->Select(kFP_PRED2D, kTRUE);
1712 }
1713 }
1714 // Case for previously used functions.
1715 else if (fTypeFit->GetSelected() == kFP_PREVFIT) {
1716 Int_t newid = kFP_ALTFUNC;
1717
1718 // Look only for those functions used in the selected object
1719 std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(fFitObject);
1720 // Then go over all those functions and add them to the list
1721 for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
1722 fFuncList->AddEntry(it->second->GetName(), newid++);
1723 }
1724
1725 // If no functions were added.
1726 if ( newid == kFP_ALTFUNC ) {
1727 // Remove the entry previous fit from fTypeFit
1728 fTypeFit->RemoveEntry(kFP_PREVFIT);
1729 if( fDim == 1 )
1730 // Select predefined 1D functions for 1D objects
1731 fTypeFit->Select(kFP_PRED1D, kTRUE);
1732 else if ( fDim == 2 )
1733 // Select predefined 2D functions for 2D objects
1734 fTypeFit->Select(kFP_PRED2D, kTRUE);
1735 else
1736 // For more than 2 dimensions, select the user functions.
1737 fTypeFit->Select(kFP_UFUNC, kTRUE);
1738 }
1739 else
1740 // If there is there are previously used functions, select
1741 // the last one inserted.
1742 fFuncList->Select(newid-1, kTRUE);
1743 }
1744}
1745
1746////////////////////////////////////////////////////////////////////////////////
1747/// Fills the list of methods depending on the minimization library
1748/// selected.
1749
1751{
1752 fMinMethodList->RemoveAll();
1753
1754 if ( fLibMinuit->GetState() == kButtonDown )
1755 {
1756 fMinMethodList->AddEntry("MIGRAD" , kFP_MIGRAD);
1757 fMinMethodList->AddEntry("SIMPLEX" , kFP_SIMPLX);
1758 fMinMethodList->AddEntry("SCAN" , kFP_SCAN);
1759 fMinMethodList->AddEntry("Combination" , kFP_COMBINATION);
1761 fStatusBar->SetText("MIGRAD",2);
1762 } else if ( fLibFumili->GetState() == kButtonDown )
1763 {
1764 fMinMethodList->AddEntry("FUMILI" , kFP_FUMILI);
1766 fStatusBar->SetText("FUMILI",2);
1767 } else if ( fLibGSL->GetState() == kButtonDown )
1768 {
1769 fMinMethodList->AddEntry("Fletcher-Reeves conjugate gradient" , kFP_GSLFR);
1770 fMinMethodList->AddEntry("Polak-Ribiere conjugate gradient" , kFP_GSLPR);
1771 fMinMethodList->AddEntry("BFGS conjugate gradient" , kFP_BFGS);
1772 fMinMethodList->AddEntry("BFGS conjugate gradient (Version 2)", kFP_BFGS2);
1773 fMinMethodList->AddEntry("Levenberg-Marquardt" , kFP_GSLLM);
1774 fMinMethodList->AddEntry("Simulated Annealing" , kFP_GSLSA);
1776 fStatusBar->SetText("CONJFR",2);
1777 } else if ( fLibGenetics->GetState() == kButtonDown )
1778 {
1779 if ( gPluginMgr->FindHandler("ROOT::Math::Minimizer","GAlibMin") ) {
1780 fMinMethodList->AddEntry("GA Lib Genetic Algorithm" , kFP_GALIB);
1782 } else if (gPluginMgr->FindHandler("ROOT::Math::Minimizer","Genetic")) {
1783 fMinMethodList->AddEntry("TMVA Genetic Algorithm" , kFP_TMVAGA);
1785 }
1786 } else // if ( fLibMinuit2->GetState() == kButtonDown )
1787 {
1788 fMinMethodList->AddEntry("MIGRAD" , kFP_MIGRAD);
1789 fMinMethodList->AddEntry("SIMPLEX" , kFP_SIMPLX);
1790 fMinMethodList->AddEntry("FUMILI" , kFP_FUMILI);
1791 fMinMethodList->AddEntry("SCAN" , kFP_SCAN);
1792 fMinMethodList->AddEntry("Combination" , kFP_COMBINATION);
1794 fStatusBar->SetText("MIGRAD",2);
1795 }
1796}
1797
1798void SearchCanvases(TSeqCollection* canvases, std::vector<TObject*>& objects)
1799{
1800 // Auxiliary function to recursively search for objects inside the
1801 // current canvases.
1802
1803 TIter canvasIter(canvases);
1804 // Iterate over all the canvases in canvases.
1805 while(TObject* obj = (TObject*) canvasIter()) {
1806 // If the object is another canvas, call this function
1807 // recursively.
1808 if ( TPad* can = dynamic_cast<TPad*>(obj))
1809 SearchCanvases(can->GetListOfPrimitives(), objects);
1810 // Otherwhise, if it's a recognised object, add it to the vector
1811 else if ( dynamic_cast<TH1*>(obj)
1812 || dynamic_cast<TGraph*>(obj)
1813 || dynamic_cast<TGraph2D*>(obj)
1814 || dynamic_cast<TMultiGraph*>(obj)
1815 || dynamic_cast<THStack*>(obj)
1816 || dynamic_cast<TTree*>(obj) ) {
1817 bool insertNew = true;
1818 // Be careful no to insert the same element twice.
1819 for ( std::vector<TObject*>::iterator i = objects.begin(); i != objects.end(); ++i )
1820 if ( (*i) == obj ) {
1821 insertNew = false;
1822 break;
1823 }
1824 // If the object is not already in the vector, then insert
1825 // it.
1826 if ( insertNew ) objects.push_back(obj);
1827 }
1828 }
1829}
1830
1831////////////////////////////////////////////////////////////////////////////////
1832/// Create a combo box with all the possible objects to be fitted.
1833
1835{
1836 // Get the title of the entry selected, so that we can select it
1837 // again once the fDataSet has been refilled.
1838 TGTextLBEntry * entry = (TGTextLBEntry*) fDataSet->GetSelectedEntry();
1839 TString selEntryStr;
1840 if ( entry ) {
1841 selEntryStr = entry->GetTitle();
1842 }
1843
1844 // Remove all the elements
1845 fDataSet->RemoveAll();
1846 std::vector<TObject*> objects;
1847
1848 // Get all the objects registered in gDirectory
1849 if (gDirectory) {
1850 TList * l = gDirectory->GetList();
1851 if (l) {
1852 TIter next(l);
1853 TObject* obj = NULL;
1854 while ( (obj = (TObject*) next()) ) {
1855 // But only if they are of a type recognized by the FitPanel
1856 if ( dynamic_cast<TH1*>(obj) ||
1857 dynamic_cast<TGraph2D*>(obj) ||
1858 dynamic_cast<TTree*>(obj) ) {
1859 objects.push_back(obj);
1860 }
1861 }
1862 }
1863 }
1864
1865 // Look for all the drawn objects. The method will take care the
1866 // same objects are not inserted twice.
1867 SearchCanvases(gROOT->GetListOfCanvases(), objects);
1868
1869 // Add all the objects stored in the vector
1870 int selected = kFP_NOSEL;
1871 // Add the No selection.
1872 Int_t newid = kFP_NOSEL;
1873 fDataSet->AddEntry("No Selection", newid++);
1874 for ( std::vector<TObject*>::iterator i = objects.begin(); i != objects.end(); ++i ) {
1875 // Insert the name as the class name followed by the name of the
1876 // object.
1877 TString name = (*i)->ClassName(); name.Append("::"); name.Append((*i)->GetName());
1878 // Check whether the names are the same!
1879 if ( selEntryStr && name == selEntryStr )
1880 selected = newid;
1881 fDataSet->AddEntry(name, newid++);
1882 }
1883
1884 // If there was an entry selected (which should be always the case
1885 // except the first time this method is executed), then make it the
1886 // selected one again.
1887 if (entry) {
1888 fDataSet->Select(selected);
1889 }
1890}
1891
1892////////////////////////////////////////////////////////////////////////////////
1893/// Create method list in a combo box.
1894
1896{
1897 TGComboBox *c = new TGComboBox(parent, id);
1898 c->AddEntry("Chi-square", kFP_MCHIS);
1899 c->AddEntry("Binned Likelihood", kFP_MBINL);
1900 c->AddEntry("Unbinned Likelihood", kFP_MUBIN);
1901 //c->AddEntry("User", kFP_MUSER); //for later use
1902 c->Select(kFP_MCHIS);
1903 return c;
1904}
1905
1906////////////////////////////////////////////////////////////////////////////////
1907/// Slot connected to advanced option button (opens a dialog).
1908
1913
1914////////////////////////////////////////////////////////////////////////////////
1915/// Slot connected to 'include emtry bins and forse all weights to 1' setting.
1916
1918{
1919 if (fEmptyBinsWghts1->GetState() == kButtonDown)
1920 if (fAllWeights1->GetState() == kButtonDown)
1921 fAllWeights1->SetState(kButtonUp, kTRUE);
1922}
1923
1924////////////////////////////////////////////////////////////////////////////////
1925
1927{
1928 if ( fUseRange->GetState() == kButtonDown ) {
1929 if (fNone->GetState() == kButtonDown || fNone->GetState() == kButtonDisabled) {
1930 // Get the function
1931 TF1* tmpTF1 = FindFunction();
1932 if ( !tmpTF1 ) {
1934 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
1935 tmpTF1 = (TF1*) GetFitObjectListOfFunctions()->FindObject( te->GetTitle() );
1936 }
1937 }
1938 // If the function has been retrieved, i.e. is a registered function.
1939 if ( tmpTF1 ) {
1940 Double_t xmin, ymin, zmin, xmax, ymax, zmax;
1941 // Get the range
1942 tmpTF1->GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
1943 // And set the sliders
1944 if ( fType != kObjectTree ) {
1945 fSliderXMin->SetNumber( xmin );
1946 fSliderXMax->SetNumber( xmax );
1948 if ( fDim > 1 ) {
1949 fSliderYMin->SetNumber( ymin );
1950 fSliderYMax->SetNumber( ymax );
1952 }
1953 }
1954 }
1955 }
1956 fUseRange->SetState(kButtonDown);
1957 }
1958}
1959
1960////////////////////////////////////////////////////////////////////////////////
1961/// Slot connected to 'set all weights to 1' setting.
1962
1964{
1965 if (fAllWeights1->GetState() == kButtonDown)
1966 if (fEmptyBinsWghts1->GetState() == kButtonDown)
1967 fEmptyBinsWghts1->SetState(kButtonUp, kTRUE);
1968}
1969
1970////////////////////////////////////////////////////////////////////////////////
1971/// Close the fit panel.
1972
1974{
1975 Hide();
1976}
1977
1978////////////////////////////////////////////////////////////////////////////////
1979/// Easy here!
1980
1986
1987////////////////////////////////////////////////////////////////////////////////
1988/// Perform a fit with current parameters' settings.
1989
1991{
1992 if (!fFitObject) return;
1993 //if (!fParentPad) return;
1994
1995 // If fNone->GetState() == kButtonDisabled means the function is
1996 // not editable, i.e. it comes from a raw C function. So in this
1997 // case, it is editable and we have to check wheather the formula
1998 // is well built.
1999 if ( fNone->GetState() != kButtonDisabled && CheckFunctionString(fEnteredFunc->GetText()) )
2000 {
2001 // If not, then show an error message and leave.
2002 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
2003 "Error...", "2) Verify the entered function string!",
2004 kMBIconStop,kMBOk, 0);
2005 return;
2006 }
2007
2008 // Set the button so that the user cannot use it while fitting, set
2009 // the mouse to watch type and so on.
2010 fFitButton->SetState(kButtonEngaged);
2011 if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kWatch);
2012 gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
2013
2014 TVirtualPad *save = nullptr;
2015 if ( fParentPad ) {
2016 fParentPad->Disconnect("RangeAxisChanged()");
2017 save = gPad;
2018 gPad = fParentPad;
2019 fParentPad->cd();
2020
2021 if (fParentPad->GetCanvas())
2022 fParentPad->GetCanvas()->SetCursor(kWatch);
2023 }
2024
2025 // Get the ranges from the sliders
2026 ROOT::Fit::DataRange drange;
2027 GetRanges(drange);
2028
2029 // Create a static pointer to fitFunc. Every second call to the
2030 // DoFit method, the old fitFunc is deleted. We need not to delete
2031 // the function after the fitting in case we want to do Advaced
2032 // graphics. The VirtualFitter need the function to be alived. One
2033 // problem, after the last fit the function is never deleted, but
2034 // ROOT's garbage collector will do the job for us.
2035 static TF1 *fitFunc = nullptr;
2036 if ( fitFunc ) {
2037 //std::cout << "TFitEditor::DoFit - deleting fit function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2038 delete fitFunc;
2039 }
2040 fitFunc = GetFitFunction();
2041
2042 std::cout << "TFitEditor::DoFit - using function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2043 // This assert
2044 if (!fitFunc) {
2045 Error("DoFit","This should have never happend, the fitfunc pointer is NULL! - Please Report" );
2046 return;
2047 }
2048
2049 // set parameters from panel in function
2050 SetParameters(fFuncPars, fitFunc);
2051 // Get the options stored in the GUI elements.
2053 Foption_t fitOpts;
2054 TString strDrawOpts;
2055 RetrieveOptions(fitOpts, strDrawOpts, mopts, fitFunc->GetNpar());
2056
2057 // Call the fit method, depending on the object to fit.
2058 switch (fType) {
2059 case kObjectHisto: {
2060
2061 TH1 *hist = dynamic_cast<TH1*>(fFitObject);
2062 if (hist)
2063 ROOT::Fit::FitObject(hist, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2064
2065 break;
2066 }
2067 case kObjectGraph: {
2068
2069 TGraph *gr = dynamic_cast<TGraph*>(fFitObject);
2070 if (gr)
2071 FitObject(gr, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2072 break;
2073 }
2074 case kObjectMultiGraph: {
2075
2076 TMultiGraph *mg = dynamic_cast<TMultiGraph*>(fFitObject);
2077 if (mg)
2078 FitObject(mg, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2079
2080 break;
2081 }
2082 case kObjectGraph2D: {
2083
2084 TGraph2D *g2d = dynamic_cast<TGraph2D*>(fFitObject);
2085 if (g2d)
2086 FitObject(g2d, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2087
2088 break;
2089 }
2090 case kObjectHStack: {
2091 // N/A
2092 break;
2093 }
2094 case kObjectTree: {
2095 // The three is a much more special case. The steps for
2096 // fitting have to be done manually here until they are
2097 // properly implemented within a FitObject method in
2098 // THFitImpl.cxx
2099
2100 // Retrieve the variables and cuts selected from the current
2101 // tree.
2102 TString variables;
2103 TString cuts;
2104 GetTreeVarsAndCuts(fDataSet, variables, cuts);
2105
2106 // This should be straight forward and the return should
2107 // never be called.
2108 TTree *tree = dynamic_cast<TTree*>(fFitObject);
2109 if ( !tree ) return;
2110
2111 // These method calls are just to set up everything for the
2112 // fitting. It's taken from another script.
2113 gROOT->ls();
2114 tree->Draw(variables,cuts,"goff");
2115
2116 auto player = tree->GetPlayer();
2117 if ( !player ) {
2118 Error("DoFit","Player reference is NULL");
2119 return;
2120 }
2121
2122 auto selector = dynamic_cast<TSelectorDraw *>(player->GetSelector());
2123 if ( !selector ) {
2124 Error("DoFit","Selector reference is NULL");
2125 return;
2126 }
2127
2128 // use pointer stored in the tree (not copy the data in)
2129 unsigned int ndim = player->GetDimension();
2130 if ( ndim == 0 ) {
2131 Error("DoFit","NDIM == 0");
2132 return;
2133 }
2134
2135 std::vector<double *> vlist;
2136 for (unsigned int i = 0; i < ndim; ++i) {
2137 double * v = selector->GetVal(i);
2138 if (v != 0) vlist.push_back(v);
2139 else
2140 std::cerr << "pointer for variable " << i << " is zero" << std::endl;
2141 }
2142 if (vlist.size() != ndim) {
2143 Error("DoFit","Vector is not complete");
2144 return;
2145 }
2146
2147 // fill the data
2148 Long64_t nrows = player->GetSelectedRows();
2149 if ( !nrows ) {
2150 Error("DoFit","NROWS == 0");
2151 return;
2152 }
2153
2154 ROOT::Fit::UnBinData * fitdata = new ROOT::Fit::UnBinData(nrows, ndim, vlist.begin());
2155
2156 for ( int i = 0; i < std::min(int(fitdata->Size()),10); ++i) {
2157 // print j coordinate
2158 for (unsigned int j = 0; j < ndim; ++j) {
2159 printf(" x_%d [%d] = %f \n", j, i,*(fitdata->Coords(i)+j) );
2160 }
2161 printf("\n");
2162 }
2163
2164
2165 //TVirtualFitter::SetDefaultFitter("Minuit");
2166 Foption_t fitOption;
2168 fitOption.Verbose=1;
2169
2170 // After all the set up is performed, then do the Fit!!
2171 ROOT::Fit::UnBinFit(fitdata, fitFunc, fitOption, minOption);
2172
2173 break;
2174 }
2175 }
2176
2177 // if SAME is set re-plot the function
2178 // useful in case histogram was drawn with HIST
2179 // and no function will be drawm)
2180 if (fDrawSame->GetState() == kButtonDown && fitFunc)
2181 fitFunc->Draw("same");
2182
2183
2184 // update parameters value shown in dialog
2185 //if (!fFuncPars) fFuncPars = new Double_t[fitFunc->GetNpar()][3];
2186 GetParameters(fFuncPars,fitFunc);
2187
2188 // Save fit data for future use as a PrevFit function.
2189 TF1* tmpTF1 = copyTF1(fitFunc);
2190 TString name = TString::Format("PrevFit-%d", (int) fPrevFit.size() + 1);
2191 if (!strstr(fitFunc->GetName(),"PrevFit"))
2192 name.Append(TString::Format("-%s", fitFunc->GetName()));
2193 tmpTF1->SetName(name.Data());
2194 fPrevFit.emplace(fFitObject, tmpTF1);
2195 fSystemFuncs.emplace_back( copyTF1(tmpTF1) );
2196
2197 float xmin = 0.f, xmax = 0.f, ymin = 0.f, ymax = 0.f, zmin = 0.f, zmax = 0.f;
2198 if ( fParentPad ) {
2199 fParentPad->Modified();
2200 // As the range is not changed, save the old values and restore
2201 // after the GUI has been updated. It would be more elegant to
2202 // disconnect the signal from fParentPad, however, this doesn't
2203 // work for unknown reasons.
2204 if ( fType != kObjectTree ) fSliderX->GetPosition(xmin, xmax);
2205 if ( fDim > 1 ) fSliderY->GetPosition(ymin, ymax);
2206 if ( fDim > 2 ) fSliderZ->GetPosition(zmin, zmax);
2207 fParentPad->Update();
2208 }
2209
2210 // In case the fit method draws something! Set the canvas!
2211 fParentPad = gPad;
2212 UpdateGUI();
2213
2214 // Change the sliders if necessary.
2215 if ( fParentPad ) {
2216 if ( fType != kObjectTree ) { fSliderX->SetPosition(xmin, xmax); DoSliderXMoved(); }
2217 if ( fType != kObjectTree && fDim > 1 ) { fSliderY->SetPosition(ymin, ymax); DoSliderYMoved(); }
2218 if ( fType != kObjectTree && fDim > 2 ) { fSliderZ->SetPosition(zmin, zmax); DoSliderZMoved(); }
2219 if (fParentPad->GetCanvas())
2220 fParentPad->GetCanvas()->SetCursor(kPointer);
2221 fParentPad->Connect("RangeAxisChanged()", "TFitEditor", this, "UpdateGUI()");
2222
2223 if (save) gPad = save;
2224 if (fSetParam->GetState() == kButtonDisabled &&
2225 fLinearFit->GetState() == kButtonUp)
2226 fSetParam->SetState(kButtonUp);
2227 }
2228
2229 // Restore the Fit button and mouse cursor to their proper state.
2230 if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kPointer);
2231 gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
2232 fFitButton->SetState(kButtonUp);
2233
2234 if ( !fTypeFit->FindEntry("Prev. Fit") )
2235 fTypeFit->InsertEntry("Prev. Fit",kFP_PREVFIT, kFP_UFUNC);
2236
2237 fDrawAdvanced->SetState(kButtonUp);
2238}
2239
2240////////////////////////////////////////////////////////////////////////////////
2241/// Check entered function string.
2242
2244{
2245 Int_t rvalue = 0;
2246 if ( fDim == 1 || fDim == 0 ) {
2247 TF1 form("tmpCheck", fname);
2248 // coverity[uninit_use_in_call]
2249 rvalue = form.IsValid() ? 0 : -1;
2250 } else if ( fDim == 2 ) {
2251 TF2 form("tmpCheck", fname);
2252 // coverity[uninit_use_in_call]
2253 rvalue = form.IsValid() ? 0 : -1;
2254 } else if ( fDim == 3 ) {
2255 TF3 form("tmpCheck", fname);
2256 // coverity[uninit_use_in_call]
2257 rvalue = form.IsValid() ? 0 : -1;
2258 }
2259
2260 return rvalue;
2261}
2262
2263////////////////////////////////////////////////////////////////////////////////
2264/// Slot connected to addition of predefined functions. It will
2265/// insert the next selected function with a plus sign so that it
2266/// doesn't override the current content of the formula.
2267
2269{
2270 static Bool_t first = kFALSE;
2271 TString s = fEnteredFunc->GetText();
2272 if (on) {
2273 if (!first) {
2274 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
2275 s += "(0)";
2276 fEnteredFunc->SetText(s.Data());
2277 first = kTRUE;
2278 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2279 }
2280 } else {
2281 first = kFALSE;
2282 }
2283}
2284////////////////////////////////////////////////////////////////////////////////
2285/// Slot connected to addition of predefined functions. It will
2286/// insert the next selected function with a plus sign so that it
2287/// doesn't override the current content of the formula.
2288
2290{
2291 /*
2292 static Bool_t first = kFALSE;
2293 TString s = fEnteredFunc->GetText();
2294 if (on) {
2295 if (!first) {
2296 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
2297 fEnteredFunc->SetText(s.Data());
2298 first = kTRUE;
2299 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2300 }
2301 } else {
2302 first = kFALSE;
2303 }*/
2304
2305 if (on) Info("DoNormAddition","Normalized addition is selected");
2306}
2307
2308////////////////////////////////////////////////////////////////////////////////
2309/// Slot connected to addition of predefined functions. It will
2310/// insert the next selected function with a plus sign so that it
2311/// doesn't override the current content of the formula.
2312
2314{
2315 /*
2316 static Bool_t first = kFALSE;
2317 TString s = fEnteredFunc->GetText();
2318 if (on) {
2319 if (!first) {
2320 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
2321 // s += "(0)";
2322 fEnteredFunc->SetText(s.Data());
2323 first = kTRUE;
2324 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2325 }
2326 } else
2327 first = kFALSE;*/
2328
2329 if (on) Info("DoConvolution","Convolution is selected");
2330}
2331
2332////////////////////////////////////////////////////////////////////////////////
2333/// Selects the data set to be fitted
2334
2336{
2337 if ( selected == kFP_NOSEL ) {
2338 DoNoSelection();
2339 return;
2340 }
2341
2342 // Get the name and class of the selected object.
2343 TGTextLBEntry* textEntry = static_cast<TGTextLBEntry*>(fDataSet->GetListBox()->GetEntry(selected));
2344 if (!textEntry) return;
2345 TString textEntryStr = textEntry->GetText()->GetString();
2346 TString name = textEntry->GetText()->GetString()+textEntry->GetText()->First(':')+2;
2347 TString className = textEntryStr(0,textEntry->GetText()->First(':'));
2348
2349 // Check the object exists in the ROOT session and it is registered
2350 TObject* objSelected(0);
2351 if ( className == "TTree" ) {
2352 // It's a tree, so the name is before the space (' ')
2353 TString lookStr;
2354 if ( name.First(' ') == kNPOS )
2355 lookStr = name;
2356 else
2357 lookStr = name(0, name.First(' '));
2358 //std::cout << "\t1 SITREE: '" << lookStr << "'" << std::endl;
2359 objSelected = gROOT->FindObject(lookStr);
2360 } else {
2361 // It's not a tree, so the name is the complete string
2362 //std::cout << "\t1 NOTREE: '" << name << "'" << std::endl;
2363 objSelected = gROOT->FindObject(name);
2364 }
2365 if ( !objSelected )
2366 {
2367 //std::cerr << "Object not found! Please report the error! " << std::endl;
2368 return;
2369 }
2370
2371 // If it is a tree, and there are no variables selected, show a dialog
2372 if ( objSelected->InheritsFrom(TTree::Class()) &&
2373 name.First(' ') == kNPOS ) {
2374 char variables[256] = {0}; char cuts[256] = {0};
2375 strlcpy(variables, "Sin input!", 256);
2376 new TTreeInput( fClient->GetRoot(), GetMainFrame(), variables, cuts );
2377 if ( strcmp ( variables, "" ) == 0 ) {
2378 DoNoSelection();
2379 return;
2380 }
2381 ProcessTreeInput(objSelected, selected, variables, cuts);
2382 }
2383
2384 // Search the canvas where the object is drawn, if any
2385 TPad* currentPad = NULL;
2386 bool found = false;
2387 std::queue<TPad*> stPad;
2388 TIter padIter( gROOT->GetListOfCanvases() );
2389 while ( TObject* canvas = static_cast<TObject*>(padIter() ) ) {
2390 if ( dynamic_cast<TPad*>(canvas) )
2391 stPad.push(dynamic_cast<TPad*>(canvas));
2392 }
2393
2394 while ( !stPad.empty() && !found ) {
2395 currentPad = stPad.front();
2396 stPad.pop();
2397 TIter elemIter( currentPad->GetListOfPrimitives() );
2398 while ( TObject* elem = static_cast<TObject*>(elemIter() ) ) {
2399 if ( elem == objSelected ) {
2400 found = true;
2401 break;
2402 } else if ( dynamic_cast<TPad*>(elem) )
2403 stPad.push( dynamic_cast<TPad*>(elem) );
2404 }
2405 }
2406
2407 // Set the proper object and canvas (if found!)
2408 SetFitObject( found ? currentPad : nullptr, objSelected, kButton1Down);
2409}
2410
2411void TFitEditor::ProcessTreeInput(TObject* objSelected, Int_t selected, TString variables, TString cuts)
2412{
2413 // If the input is valid, insert the tree with the selections as an entry to fDataSet
2414 TString entryName = (objSelected)->ClassName(); entryName.Append("::"); entryName.Append((objSelected)->GetName());
2415 entryName.Append(" (\""); entryName.Append(variables); entryName.Append("\", \"");
2416 entryName.Append(cuts); entryName.Append("\")");
2417 Int_t newid = fDataSet->GetNumberOfEntries() + kFP_NOSEL;
2418 fDataSet->InsertEntry(entryName, newid, selected );
2419 fDataSet->Select(newid);
2420}
2421
2422////////////////////////////////////////////////////////////////////////////////
2423/// Slot connected to predefined fit function settings.
2424
2426{
2427 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
2428
2429 // check that selected passesd value is the correct one in the TextEntry
2430 R__ASSERT( selected == te->EntryId());
2431 //std::cout << "calling do function " << selected << " " << te->GetTitle() << " function " << te->EntryId() << std::endl;
2432 //selected = te->EntryId();
2433
2434 bool editable = false;
2435 if (fNone -> GetState() == kButtonDown || fNone->GetState() == kButtonDisabled)
2436 {
2437 // Get the function selected and check weather it is a raw C
2438 // function or not
2439 TF1* tmpTF1 = FindFunction();
2440 if ( !tmpTF1 )
2441 {
2443 tmpTF1 = (TF1*) GetFitObjectListOfFunctions()->FindObject( te->GetTitle() );
2444 }
2445 if ( tmpTF1 && strcmp(tmpTF1->GetExpFormula(), "") )
2446 {
2447 editable = kTRUE;
2448 fEnteredFunc->SetText(tmpTF1->GetExpFormula());
2449 }
2450 else
2451 {
2452 if ( selected <= kFP_USER )
2453 editable = kTRUE;
2454 else
2455 editable = kFALSE;
2456 fEnteredFunc->SetText(te->GetTitle());
2457 }
2458 // Once you have the function, set the editable.
2459 SetEditable(editable);
2460 }
2461 else if (fAdd -> GetState() == kButtonDown)
2462 {
2463 // If the add button is down don't replace the fEnteredFunc text
2464 Int_t np = 0;
2465 TString s = "";
2466 if (!strcmp(fEnteredFunc->GetText(), ""))
2467 {
2468 fEnteredFunc->SetText(te->GetTitle());
2469 }
2470 else
2471 {
2472 s = fEnteredFunc->GetTitle();
2473 TFormula tmp("tmp", fEnteredFunc->GetText());
2474 np = tmp.GetNpar();
2475 }
2476 if (np)
2477 s += TString::Format("+%s(%d)", te->GetTitle(), np);
2478 else
2479 s += TString::Format("%s(%d)", te->GetTitle(), np);
2480 fEnteredFunc->SetText(s.Data());
2481 editable = true;
2482 }
2483 else if (fNormAdd->GetState() == kButtonDown)
2484 {
2485 // If the normadd button is down don't replace the fEnteredFunc text
2486 Int_t np = 0;
2487 TString s = "";
2488 if (!strcmp(fEnteredFunc->GetText(), ""))
2489 {
2490 fEnteredFunc->SetText(te->GetTitle());
2491 }
2492 else
2493 {
2494 s = fEnteredFunc->GetTitle();
2495 TFormula tmp("tmp", fEnteredFunc->GetText());
2496 np = tmp.GetNpar();
2497 }
2498 if (np)
2499 s += TString::Format("+%s", te->GetTitle());
2500 else
2501 s += TString::Format("%s", te->GetTitle());
2502 fEnteredFunc->SetText(s.Data());
2503 //std::cout <<fEnteredFunc->GetText()<<std::endl;
2504 editable = true;
2505 }
2506 else if (fConv->GetState() == kButtonDown)
2507 {
2508 // If the conv button is down don't replace the fEnteredFunc text
2509 Int_t np = 0;
2510 TString s = "";
2511 if (!strcmp(fEnteredFunc->GetText(), ""))
2512 fEnteredFunc->SetText(te->GetTitle());
2513 else
2514 {
2515 s = fEnteredFunc->GetTitle();
2516 TFormula tmp("tmp", fEnteredFunc->GetText());
2517 np = tmp.GetNpar();
2518 }
2519 if (np)
2520 s += TString::Format("*%s", te->GetTitle());
2521 else
2522 s += TString::Format("%s", te->GetTitle());
2523 fEnteredFunc->SetText(s.Data());
2524 //std::cout <<fEnteredFunc->GetText()<<std::endl;
2525 editable = true;
2526 }
2527
2528
2529 // Get the final name in fEnteredFunc to process the function that
2530 // it would create
2531 TString tmpStr = fEnteredFunc->GetText();
2532
2533 // create TF1 with the passed string. Delete previous one if existing
2534 if (tmpStr.Contains("pol") || tmpStr.Contains("++")) {
2535 fLinearFit->SetState(kButtonDown, kTRUE);
2536 } else {
2537 fLinearFit->SetState(kButtonUp, kTRUE);
2538 }
2539
2540 fEnteredFunc->SelectAll();
2541 fSelLabel->SetText(tmpStr.Sizeof()>30?tmpStr(0,30)+"...":tmpStr);
2542 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2543
2544 // reset function parameters if the number of parameters of the new
2545 // function is different from the old one!
2546 TF1* fitFunc = GetFitFunction();
2547 //std::cout << "TFitEditor::DoFunction - using function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2548
2549 if ( fitFunc && (unsigned int) fitFunc->GetNpar() != fFuncPars.size() ) {
2550 if (fAdd->GetState() == kButtonDown || fNormAdd->GetState() == kButtonDown || fConv->GetState() == kButtonDown)
2551 fFuncPars.resize(fitFunc->GetNpar());
2552 else
2553 fFuncPars.clear();
2554 }
2555 if ( fitFunc ) {
2556 //std::cout << "TFitEditor::DoFunction - deleting function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2557 delete fitFunc;
2558 }
2559}
2560
2561////////////////////////////////////////////////////////////////////////////////
2562/// Slot connected to entered function in text entry.
2563
2565{
2566 if (!strcmp(fEnteredFunc->GetText(), "")) return;
2567
2568 // Check if the function is well built
2569 Int_t ok = CheckFunctionString(fEnteredFunc->GetText());
2570
2571 if (ok != 0) {
2572 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
2573 "Error...", "3) Verify the entered function string!",
2574 kMBIconStop,kMBOk, 0);
2575 return;
2576 }
2577
2578 // And set the label with the entered text if everything is fine.
2579 TString s = fEnteredFunc->GetText();
2580 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
2581 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2582}
2583
2584////////////////////////////////////////////////////////////////////////////////
2585/// Slot connected to linear fit settings.
2586
2588{
2589 if (fLinearFit->GetState() == kButtonDown) {
2590 //fSetParam->SetState(kButtonDisabled);
2591 fBestErrors->SetState(kButtonDisabled);
2593 fEnableRobust->SetState(kButtonUp);
2594 //fNoChi2->SetState(kButtonUp);
2595 } else {
2596 //fSetParam->SetState(kButtonUp);
2597 fBestErrors->SetState(kButtonUp);
2598 fImproveResults->SetState(kButtonUp);
2599 fEnableRobust->SetState(kButtonDisabled);
2600 fRobustValue->SetState(kFALSE);
2601 //fNoChi2->SetState(kButtonDisabled);
2602 }
2603}
2604
2605////////////////////////////////////////////////////////////////////////////////
2606/// Slot connected to 'no chi2' option settings.
2607
2609{
2610 //LM: no need to do operations here
2611 // if (fLinearFit->GetState() == kButtonUp)
2612 // fLinearFit->SetState(kButtonDown, kTRUE);
2613}
2614////////////////////////////////////////////////////////////////////////////////
2615/// Slot connected to 'robust fitting' option settings.
2616
2618{
2619 if (fEnableRobust->GetState() == kButtonDown)
2620 fRobustValue->SetState(kTRUE);
2621 else
2622 fRobustValue->SetState(kFALSE);
2623}
2624
2625////////////////////////////////////////////////////////////////////////////////
2626/// Slot connected to 'no storing, no drawing' settings.
2627
2629{
2630 if (fNoDrawing->GetState() == kButtonUp)
2631 fNoDrawing->SetState(kButtonDown);
2632}
2633
2634////////////////////////////////////////////////////////////////////////////////
2635/// Slot connected to print option settings.
2636
2638{
2639 // Change the states of the buttons depending of which one is
2640 // selected.
2641 TGButton *btn = (TGButton *) gTQSender;
2642 Int_t id = btn->WidgetId();
2643 switch (id) {
2644 case kFP_PDEF:
2645 if (on) {
2646 fOptDefault->SetState(kButtonDown);
2647 fOptVerbose->SetState(kButtonUp);
2648 fOptQuiet->SetState(kButtonUp);
2649 }
2650 fStatusBar->SetText("Prn: DEF",4);
2651 break;
2652 case kFP_PVER:
2653 if (on) {
2654 fOptVerbose->SetState(kButtonDown);
2655 fOptDefault->SetState(kButtonUp);
2656 fOptQuiet->SetState(kButtonUp);
2657 }
2658 fStatusBar->SetText("Prn: VER",4);
2659 break;
2660 case kFP_PQET:
2661 if (on) {
2662 fOptQuiet->SetState(kButtonDown);
2663 fOptDefault->SetState(kButtonUp);
2664 fOptVerbose->SetState(kButtonUp);
2665 }
2666 fStatusBar->SetText("Prn: QT",4);
2667 default:
2668 break;
2669 }
2670}
2671
2672////////////////////////////////////////////////////////////////////////////////
2673/// Reset all fit parameters.
2674
2676{
2677 if ( fParentPad ) {
2678 fParentPad->Modified();
2679 fParentPad->Update();
2680 }
2681 fEnteredFunc->SetText("gaus");
2682
2683 // To restore temporary points and sliders
2684 UpdateGUI();
2685
2686 if (fLinearFit->GetState() == kButtonDown)
2687 fLinearFit->SetState(kButtonUp, kTRUE);
2688 if (fBestErrors->GetState() == kButtonDown)
2689 fBestErrors->SetState(kButtonUp, kFALSE);
2690 if (fUseRange->GetState() == kButtonDown)
2691 fUseRange->SetState(kButtonUp, kFALSE);
2692 if (fAllWeights1->GetState() == kButtonDown)
2693 fAllWeights1->SetState(kButtonUp, kFALSE);
2694 if (fEmptyBinsWghts1->GetState() == kButtonDown)
2695 fEmptyBinsWghts1->SetState(kButtonUp, kFALSE);
2696 if (fImproveResults->GetState() == kButtonDown)
2697 fImproveResults->SetState(kButtonUp, kFALSE);
2698 if (fAdd2FuncList->GetState() == kButtonDown)
2699 fAdd2FuncList->SetState(kButtonUp, kFALSE);
2700 if (fUseGradient->GetState() == kButtonDown)
2701 fUseGradient->SetState(kButtonUp, kFALSE);
2702 if (fEnableRobust->GetState() == kButtonDown)
2703 fEnableRobust->SetState(kButtonUp, kFALSE);
2704 // if (fNoChi2->GetState() == kButtonDown)
2705 // fNoChi2->SetState(kButtonUp, kFALSE);
2706 if (fDrawSame->GetState() == kButtonDown)
2707 fDrawSame->SetState(kButtonUp, kFALSE);
2708 if (fNoDrawing->GetState() == kButtonDown)
2709 fNoDrawing->SetState(kButtonUp, kFALSE);
2710 if (fNoStoreDrawing->GetState() == kButtonDown)
2711 fNoStoreDrawing->SetState(kButtonUp, kFALSE);
2712 fNone->SetState(kButtonDown, kTRUE);
2713 fFuncList->Select(1, kTRUE);
2714
2715 // minimization tab
2716 if (fLibMinuit->GetState() != kButtonDown)
2717 fLibMinuit->SetState(kButtonDown, kTRUE);
2719 if (fOptDefault->GetState() != kButtonDown)
2720 fOptDefault->SetState(kButtonDown, kTRUE);
2723 fErrorScale->ReturnPressed();
2724 }
2727 fTolerance->ReturnPressed();
2728 }
2731 fIterations->ReturnPressed();
2732 }
2733}
2734
2735////////////////////////////////////////////////////////////////////////////////
2736/// Open set parameters dialog.
2737
2739{
2740 // Get the function.
2741 TF1* fitFunc = GetFitFunction();
2742 //std::cout << "TFitEditor::DoSetParameters - using function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2743
2744 if (!fitFunc) { Error("DoSetParameters","NUll function"); return; }
2745
2746 // case of special functions (gaus, expo, etc...) if the function
2747 // has not defined the parameters yet. For those, don't let the
2748 // parameters to be all equal to 0, as we can provide some good
2749 // starting value.
2750 if (fFuncPars.size() == 0) {
2751 switch (fType) {
2752 case kObjectHisto:
2753 InitParameters( fitFunc, (TH1*)fFitObject) ;
2754 break;
2755 case kObjectGraph:
2756 InitParameters( fitFunc, ((TGraph*)fFitObject));
2757 break;
2758 case kObjectMultiGraph:
2759 InitParameters( fitFunc, ((TMultiGraph*)fFitObject));
2760 break;
2761 case kObjectGraph2D:
2762 InitParameters( fitFunc, ((TGraph2D*)fFitObject));
2763 break;
2764 case kObjectHStack:
2765 case kObjectTree:
2766 default:
2767 break;
2768 }
2769 // The put these parameters into the fFuncPars structure
2770 GetParameters(fFuncPars, fitFunc);
2771 }
2772 else {
2773 // Otherwise, put the parameters in the function
2774 SetParameters(fFuncPars, fitFunc);
2775 }
2776
2777 if ( fParentPad ) fParentPad->Disconnect("RangeAxisChanged()");
2778 Int_t ret = 0;
2779 /// fit parameter dialog willbe deleted automatically when closed
2780 new TFitParametersDialog(gClient->GetDefaultRoot(), GetMainFrame(),
2781 fitFunc, fParentPad, &ret);
2782
2783 // Once the parameters are set in the fitfunction, save them.
2784 GetParameters(fFuncPars, fitFunc);
2785
2786 // check return code to see if parameters settings have been modified
2787 // in this case we need to set the B option when fitting
2788 if (ret) fChangedParams = kTRUE;
2789
2790
2791 if ( fParentPad ) fParentPad->Connect("RangeAxisChanged()", "TFitEditor", this, "UpdateGUI()");
2792
2793 if ( fNone->GetState() != kButtonDisabled ) {
2794 //std::cout << "TFitEditor::DoSetParameters - deleting function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2795 delete fitFunc;
2796 }
2797}
2798
2799////////////////////////////////////////////////////////////////////////////////
2800/// Slot connected to range settings on x-axis.
2801
2803{
2804 if ( !fFitObject ) return;
2805
2806 fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ) );
2807 fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ) );
2808
2809 fUseRange->SetState(kButtonUp);
2810
2811 DrawSelection();
2812}
2813
2814////////////////////////////////////////////////////////////////////////////////
2815/// Draws the square around the object showing where the limits for
2816/// fitting are.
2817
2819{
2820#ifndef R__HAS_COCOA
2821 static Int_t px1old, py1old, px2old, py2old; // to remember the square drawn.
2822#endif
2823
2824 if ( !fParentPad ) return;
2825
2826 if (restore) {
2827#ifndef R__HAS_COCOA
2828 px1old = fParentPad->XtoAbsPixel(fParentPad->GetUxmin());
2829 py1old = fParentPad->YtoAbsPixel(fParentPad->GetUymin());
2830 px2old = fParentPad->XtoAbsPixel(fParentPad->GetUxmax());
2831 py2old = fParentPad->YtoAbsPixel(fParentPad->GetUymax());
2832#endif
2833 return;
2834 }
2835
2836 Int_t px1,py1,px2,py2;
2837
2838 TVirtualPad *save = 0;
2839 save = gPad;
2840 gPad = fParentPad;
2841 gPad->cd();
2842
2843 Double_t xleft = 0;
2844 Double_t xright = 0;
2845 xleft = fXaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5));
2846 xright = fXaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5));
2847
2848 Float_t ymin, ymax;
2849 if ( fDim > 1 )
2850 {
2851 ymin = fYaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5));//gPad->GetUymin();
2852 ymax = fYaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5));//gPad->GetUymax();
2853 }
2854 else
2855 {
2856 ymin = gPad->GetUymin();
2857 ymax = gPad->GetUymax();
2858 }
2859
2860 px1 = gPad->XtoAbsPixel(xleft);
2861 py1 = gPad->YtoAbsPixel(ymin);
2862 px2 = gPad->XtoAbsPixel(xright);
2863 py2 = gPad->YtoAbsPixel(ymax);
2864
2865 if (gPad->GetCanvas()) gPad->GetCanvas()->FeedbackMode(kTRUE);
2866 gPad->SetLineWidth(1);
2867 gPad->SetLineColor(2);
2868#ifndef R__HAS_COCOA
2869 // With Cocoa XOR is fake, so no need in erasing the old box, it's
2870 // done by clearing the backing store and repainting inside a special
2871 // window.
2872 gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
2873
2874 px1old = px1;
2875 py1old = py1;
2876 px2old = px2;
2877 py2old = py2;
2878#endif // R__HAS_COCOA
2879 gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
2880
2881 if(save) gPad = save;
2882}
2883
2884////////////////////////////////////////////////////////////////////////////////
2885/// Sincronize the numeric sliders with the graphical one.
2886
2888{
2889 if ( fSliderXMin->GetNumber() > fSliderXMax->GetNumber() ) {
2890 float xmin, xmax;
2891 fSliderX->GetPosition(xmin, xmax);
2892 fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( xmin ) ) );
2893 fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( xmax ) ) );
2894 return;
2895 }
2896
2897 fSliderX->SetPosition(fXaxis->FindBin( fSliderXMin->GetNumber() ),
2898 fXaxis->FindBin( fSliderXMax->GetNumber() ));
2899
2900 fUseRange->SetState(kButtonUp);
2901
2902 DrawSelection();
2903}
2904
2905////////////////////////////////////////////////////////////////////////////////
2906/// Slot connected to range settings on y-axis.
2907
2909{
2910 if ( !fFitObject ) return;
2911
2912 fSliderYMin->SetNumber( fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ) );
2913 fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ) );
2914
2915 fUseRange->SetState(kButtonUp);
2916
2917 DrawSelection();
2918}
2919
2920////////////////////////////////////////////////////////////////////////////////
2921///syncronize the numeric slider with the graphical one.
2922
2924{
2925 if ( fSliderYMin->GetNumber() > fSliderYMax->GetNumber() ) {
2926 float ymin, ymax;
2927 fSliderY->GetPosition(ymin, ymax);
2928 fSliderYMin->SetNumber( fYaxis->GetBinLowEdge( static_cast<Int_t>( ymin ) ) );
2929 fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( ymax ) ) );
2930 return;
2931 }
2932
2933 fSliderY->SetPosition( fYaxis->FindBin( fSliderYMin->GetNumber() ),
2934 fYaxis->FindBin( fSliderYMax->GetNumber() ));
2935
2936 fUseRange->SetState(kButtonUp);
2937
2938 DrawSelection();
2939}
2940
2941////////////////////////////////////////////////////////////////////////////////
2942/// Slot connected to range settings on z-axis.
2943
2947
2948////////////////////////////////////////////////////////////////////////////////
2949/// Open a dialog for getting a user defined method.
2950
2952{
2953 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
2954 "Info", "Dialog of user method is not implemented yet",
2956}
2957
2958////////////////////////////////////////////////////////////////////////////////
2959/// Set the function to be used in performed fit.
2960
2961void TFitEditor::SetFunction(const char *function)
2962{
2963 fEnteredFunc->SetText(function);
2964}
2965
2966////////////////////////////////////////////////////////////////////////////////
2967/// Check whether the object suitable for fitting and set
2968/// its type, dimension and method combo box accordingly.
2969
2971{
2972 Bool_t set = kFALSE;
2973
2974 // For each kind of object, set a different status in the fit
2975 // panel.
2976 if (obj->InheritsFrom(TGraph::Class())) {
2978 set = kTRUE;
2979 fDim = 1;
2980 fMethodList->RemoveAll();
2981 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
2982 fMethodList->Select(kFP_MCHIS, kFALSE);
2983 fRobustValue->SetState(kTRUE);
2984 fRobustValue->GetNumberEntry()->SetToolTipText("Set robust value");
2985 } else if (obj->InheritsFrom(TGraph2D::Class())) {
2987 set = kTRUE;
2988 fDim = 2;
2989 fMethodList->RemoveAll();
2990 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
2991 fMethodList->Select(kFP_MCHIS, kFALSE);
2992 } else if (obj->InheritsFrom(THStack::Class())) {
2994 set = kTRUE;
2995 TH1 *hist = (TH1 *)((THStack *)obj)->GetHists()->First();
2996 fDim = hist->GetDimension();
2997 fMethodList->RemoveAll();
2998 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
2999 fMethodList->Select(kFP_MCHIS, kFALSE);
3000 } else if (obj->InheritsFrom(TTree::Class())) {
3002 set = kTRUE;
3003 TString variables, cuts;
3004 GetTreeVarsAndCuts(fDataSet, variables, cuts);
3005 fDim = 1;
3006 for ( int i = 0; i < variables.Length() && fDim <= 2; ++i )
3007 if ( ':' == variables[i] ) fDim += 1;
3008 // For any three of dimension bigger than 2, set the dimension
3009 // to 0, as we cannot infer the dimension from the TF1s, it's
3010 // better to have 0 as reference.
3011 if ( fDim > 2 ) fDim = 0;
3012 fMethodList->RemoveAll();
3013 fMethodList->AddEntry("Unbinned Likelihood", kFP_MUBIN);
3014 fMethodList->Select(kFP_MUBIN, kFALSE);
3015 } else if (obj->InheritsFrom(TH1::Class())){
3017 set = kTRUE;
3018 fDim = ((TH1*)obj)->GetDimension();
3019 fMethodList->RemoveAll();
3020 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
3021 fMethodList->AddEntry("Binned Likelihood", kFP_MBINL);
3022 fMethodList->Select(kFP_MCHIS, kFALSE);
3023 } else if (obj->InheritsFrom(TMultiGraph::Class())) {
3025 set = kTRUE;
3026 fDim = 1;
3027 fMethodList->RemoveAll();
3028 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
3029 fMethodList->Select(kFP_MCHIS, kFALSE);
3030 fRobustValue->SetState(kTRUE);
3031 fRobustValue->GetNumberEntry()->SetToolTipText("Set robust value");
3032 }
3033
3034 // Depending on the dimension of the object, allow the
3035 // visualization of sliders.
3036 if ( fDim < 2 || fType == kObjectTree )
3037 fGeneral->HideFrame(fSliderYParent);
3038 else
3039 fGeneral->ShowFrame(fSliderYParent);
3040
3041 if ( fDim < 1 || fType == kObjectTree )
3042 fGeneral->HideFrame(fSliderXParent);
3043 else
3044 fGeneral->ShowFrame(fSliderXParent);
3045
3046 // And also, depending on the dimension, add predefined functions.
3047 if ( fDim == 1 ) {
3048 if ( !fTypeFit->FindEntry("Predef-1D") )
3049 fTypeFit->InsertEntry("Predef-1D", kFP_PRED1D, kFP_PREVFIT);
3050 } else {
3051 if ( fTypeFit->FindEntry("Predef-1D") )
3052 fTypeFit->RemoveEntry(kFP_PRED1D);
3053 }
3054
3055 if ( fDim == 2 ) {
3056 if ( !fTypeFit->FindEntry("Predef-2D") )
3057 fTypeFit->InsertEntry("Predef-2D", kFP_PRED2D, kFP_PREVFIT);
3058 } else {
3059 if ( fTypeFit->FindEntry("Predef-2D") )
3060 fTypeFit->RemoveEntry(kFP_PRED2D);
3061 }
3062
3063 return set;
3064}
3065
3066////////////////////////////////////////////////////////////////////////////////
3067/// Show object name on the top.
3068
3070{
3071 TString name;
3072 bool isTree = false;
3073
3074 // Build the string to be compared to look for the object.
3075 if (obj) {
3076 name = obj->ClassName();
3077 name.Append("::");
3078 name.Append(obj->GetName());
3079 isTree = strcmp(obj->ClassName(), "TTree") == 0;
3080 } else {
3081 name = "No object selected";
3082 }
3083 fStatusBar->SetText(name.Data(),0);
3084
3085 // If the selection was done in the fDataSet combo box, there is no need
3086 // to search through the list
3087 TGTextLBEntry* selectedEntry = static_cast<TGTextLBEntry*> ( fDataSet->GetSelectedEntry());
3088 if ( selectedEntry ) {
3089 TString selectedName = selectedEntry->GetText()->GetString();
3090 if ( isTree )
3091 selectedName = selectedName(0, selectedName.First(' '));
3092 if ( name.CompareTo(selectedName) == 0 ) {
3093 Layout();
3094 return;
3095 }
3096 }
3097
3098 // Search through the list for the object
3099 Int_t entryId = kFP_NOSEL+1;
3100 bool found = false;
3101 while ( TGTextLBEntry* entry = static_cast<TGTextLBEntry*>
3102 ( fDataSet->GetListBox()->GetEntry(entryId)) ) {
3103 TString compareName = entry->GetText()->GetString();
3104 if ( isTree )
3105 compareName = compareName(0, compareName.First(' '));
3106 if ( name.CompareTo(compareName) == 0 ) {
3107 // If the object is found, select it
3108 fDataSet->Select(entryId, false);
3109 found = true;
3110 break;
3111 }
3112 entryId += 1;
3113 }
3114
3115 // If the object was not found, add it and select it.
3116 if ( !found ) {
3117 fDataSet->AddEntry(name.Data(), entryId);
3118 fDataSet->Select(entryId, kTRUE);
3119 }
3120
3121 Layout();
3122}
3123
3124////////////////////////////////////////////////////////////////////////////////
3125/// Get draw options of the selected object.
3126
3128{
3129 if (!fParentPad) return "";
3130
3131 TListIter next(fParentPad->GetListOfPrimitives());
3132 TObject *obj;
3133 while ((obj = next())) {
3134 if (obj == fFitObject) return next.GetOption();
3135 }
3136 return "";
3137}
3138
3139////////////////////////////////////////////////////////////////////////////////
3140/// Set selected minimization library in use.
3141
3143{
3144 TGButton *bt = (TGButton *)gTQSender;
3145 Int_t id = bt->WidgetId();
3146
3147 switch (id) {
3148
3149 // Depending on the selected library, set the state of the rest
3150 // of the buttons.
3151 case kFP_LMIN:
3152 {
3153 if (on) {
3154 fLibMinuit->SetState(kButtonDown);
3155 fLibMinuit2->SetState(kButtonUp);
3156 fLibFumili->SetState(kButtonUp);
3157 if ( fLibGSL->GetState() != kButtonDisabled )
3158 fLibGSL->SetState(kButtonUp);
3159 if ( fLibGenetics->GetState() != kButtonDisabled )
3160 fLibGenetics->SetState(kButtonUp);
3161 fStatusBar->SetText("LIB Minuit", 1);
3162 }
3163
3164 }
3165 break;
3166
3167 case kFP_LMIN2:
3168 {
3169 if (on) {
3170 fLibMinuit->SetState(kButtonUp);
3171 fLibMinuit2->SetState(kButtonDown);
3172 fLibFumili->SetState(kButtonUp);
3173 if ( fLibGSL->GetState() != kButtonDisabled )
3174 fLibGSL->SetState(kButtonUp);
3175 if ( fLibGenetics->GetState() != kButtonDisabled )
3176 fLibGenetics->SetState(kButtonUp);
3177 fStatusBar->SetText("LIB Minuit2", 1);
3178 }
3179 }
3180 break;
3181
3182 case kFP_LFUM:
3183 {
3184 if (on) {
3185 fLibMinuit->SetState(kButtonUp);
3186 fLibMinuit2->SetState(kButtonUp);
3187 fLibFumili->SetState(kButtonDown);
3188 if ( fLibGSL->GetState() != kButtonDisabled )
3189 fLibGSL->SetState(kButtonUp);
3190 if ( fLibGenetics->GetState() != kButtonDisabled )
3191 fLibGenetics->SetState(kButtonUp);
3192 fStatusBar->SetText("LIB Fumili", 1);
3193 }
3194 }
3195 break;
3196 case kFP_LGSL:
3197 {
3198 if (on) {
3199 fLibMinuit->SetState(kButtonUp);
3200 fLibMinuit2->SetState(kButtonUp);
3201 fLibFumili->SetState(kButtonUp);
3202 if ( fLibGSL->GetState() != kButtonDisabled )
3203 fLibGSL->SetState(kButtonDown);
3204 if ( fLibGenetics->GetState() != kButtonDisabled )
3205 fLibGenetics->SetState(kButtonUp);
3206 fStatusBar->SetText("LIB GSL", 1);
3207 }
3208 }
3209 break;
3210 case kFP_LGAS:
3211 {
3212 if (on) {
3213 fLibMinuit->SetState(kButtonUp);
3214 fLibMinuit2->SetState(kButtonUp);
3215 fLibFumili->SetState(kButtonUp);
3216 if ( fLibGSL->GetState() != kButtonDisabled )
3217 fLibGSL->SetState(kButtonUp);
3218 if ( fLibGenetics->GetState() != kButtonDisabled )
3219 fLibGenetics->SetState(kButtonDown);
3220 fStatusBar->SetText("LIB Genetics", 1);
3221 }
3222 }
3223 default:
3224 break;
3225 }
3227}
3228
3229////////////////////////////////////////////////////////////////////////////////
3230/// Set selected minimization method in use.
3231
3233{
3234 if ( fMinMethodList->GetSelected() == kFP_MIGRAD )
3235 fStatusBar->SetText("MIGRAD",2);
3236 else if ( fMinMethodList->GetSelected() == kFP_FUMILI)
3237 fStatusBar->SetText("FUMILI",2);
3238 else if ( fMinMethodList->GetSelected() == kFP_SIMPLX )
3239 fStatusBar->SetText("SIMPLEX",2);
3240 else if ( fMinMethodList->GetSelected() == kFP_SCAN )
3241 fStatusBar->SetText("SCAN",2);
3242 else if ( fMinMethodList->GetSelected() == kFP_COMBINATION )
3243 fStatusBar->SetText("Combination",2);
3244 else if ( fMinMethodList->GetSelected() == kFP_GSLFR )
3245 fStatusBar->SetText("CONJFR",2);
3246 else if ( fMinMethodList->GetSelected() == kFP_GSLPR )
3247 fStatusBar->SetText("CONJPR",2);
3248 else if ( fMinMethodList->GetSelected() == kFP_BFGS )
3249 fStatusBar->SetText("BFGS",2);
3250 else if ( fMinMethodList->GetSelected() == kFP_BFGS2 )
3251 fStatusBar->SetText("BFGS2",2);
3252 else if ( fMinMethodList->GetSelected() == kFP_GSLLM )
3253 fStatusBar->SetText("GSLLM",2);
3254 else if ( fMinMethodList->GetSelected() == kFP_GSLSA)
3255 fStatusBar->SetText("SimAn",2);
3256 else if ( fMinMethodList->GetSelected() == kFP_TMVAGA )
3257 fStatusBar->SetText("TMVAGA",2);
3258 else if ( fMinMethodList->GetSelected() == kFP_GALIB )
3259 fStatusBar->SetText("GALIB",2);
3260
3261
3262}
3263
3264////////////////////////////////////////////////////////////////////////////////
3265/// Set the maximum number of iterations.
3266
3268{
3269 Long_t itr = fIterations->GetIntNumber();
3270 fStatusBar->SetText(Form("Itr: %ld",itr),2);
3271}
3272
3273////////////////////////////////////////////////////////////////////////////////
3274/// Create section title in the GUI.
3275
3276void TFitEditor::MakeTitle(TGCompositeFrame *parent, const char *title)
3277{
3278 TGCompositeFrame *ht = new TGCompositeFrame(parent, 350, 10,
3280 ht->AddFrame(new TGLabel(ht, title),
3281 new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
3282 ht->AddFrame(new TGHorizontal3DLine(ht),
3283 new TGLayoutHints(kLHintsExpandX | kLHintsCenterY, 5, 5, 2, 2));
3284 parent->AddFrame(ht, new TGLayoutHints(kLHintsTop, 5, 0, 5, 0));
3285}
3286
3287////////////////////////////////////////////////////////////////////////////////
3288/// Look in the list of function for TF1. If a TF1 is
3289/// found in the list of functions, it will be returned
3290
3292{
3293 // Get the list of functions of the fit object
3295 TF1* func = 0;
3296
3297 // If it exists
3298 if ( lf ) {
3299 // Add the posibility to select previous fit function
3300 if ( !fTypeFit->FindEntry("Prev. Fit") )
3301 fTypeFit->InsertEntry("Prev. Fit",kFP_PREVFIT, kFP_UFUNC);
3302
3303 // Then add all these functions to the fPrefFit structure.
3304 TObject *obj2;
3305 TIter next(lf, kIterForward);
3306 // Go over all the elements in lf
3307 while ((obj2 = next())) {
3308 if (obj2->InheritsFrom(TF1::Class())) {
3309 func = (TF1 *)obj2;
3310 fPrevFitIter it;
3311 // No go over all elements in fPrevFit
3312 for ( it = fPrevFit.begin(); it != fPrevFit.end(); ++it) {
3313 // To see wheather the object corresponds with fFitObject
3314 if ( it->first != fFitObject ) continue;
3315 // And if so, whether the function is already included
3316 if ( strcmp( func->GetName(), it->second->GetName() ) == 0 )
3317 break;
3318 if ( strcmp( func->GetName(), "PrevFitTMP" ) == 0 )
3319 break;
3320 }
3321 // Only if the function is not already in fPrevFit, the
3322 // breaks in the loops would make it to be different to
3323 // fPrevFit.end() if the function is already stored
3324 if ( it == fPrevFit.end() ) {
3325 fPrevFit.emplace(fFitObject, copyTF1(func));
3326 }
3327 }
3328 }
3329
3330 // Select the PrevFit set
3331 fTypeFit->Select(kFP_PREVFIT);
3332 // And fill the function list
3334 fDrawAdvanced->SetState(kButtonUp);
3335
3336
3337 } else {
3338 // If there is no prev fit functions.
3339 fTypeFit->Select(kFP_UFUNC);
3340 // Call FillFunctionList as it might happen that the user is
3341 // changing from a TTree to another one, and thus the fFuncList
3342 // if not properly filled
3344 }
3345
3346 fDrawAdvanced->SetState(kButtonDisabled);
3347
3348 return func;
3349}
3350
3351////////////////////////////////////////////////////////////////////////////////
3352/// Retrieve the fitting options from all the widgets.
3353
3355{
3356 drawOpts = "";
3357
3358 fitOpts.Range = (fUseRange->GetState() == kButtonDown);
3359 fitOpts.Integral = (fIntegral->GetState() == kButtonDown);
3360 fitOpts.More = (fImproveResults->GetState() == kButtonDown);
3361 fitOpts.Errors = (fBestErrors->GetState() == kButtonDown);
3362 fitOpts.Like = (fMethodList->GetSelected() != kFP_MCHIS);
3363
3364 if (fEmptyBinsWghts1->GetState() == kButtonDown)
3365 fitOpts.W1 = 2;
3366 else if (fAllWeights1->GetState() == kButtonDown)
3367 fitOpts.W1 = 1;
3368
3369 TString tmpStr = fEnteredFunc->GetText();
3370 if ( !(fLinearFit->GetState() == kButtonDown) &&
3371 (tmpStr.Contains("pol") || tmpStr.Contains("++")) )
3372 fitOpts.Minuit = 1;
3373
3374 // if ( (int) fFuncPars.size() == npar )
3375 // for ( Int_t i = 0; i < npar; ++i )
3376 // if ( fFuncPars[i][PAR_MIN] != fFuncPars[i][PAR_MAX] )
3377 //
3378
3379 // //fitOpts.Bound = 1;
3380 // break;
3381 // }
3382
3383 if (fChangedParams) {
3384 //std::cout << "Params have changed setting the Bound option " << std::endl;
3385 fitOpts.Bound = 1;
3386 fChangedParams = kFALSE; // reset
3387 }
3388
3389 //fitOpts.Nochisq = (fNoChi2->GetState() == kButtonDown);
3390 fitOpts.Nostore = (fNoStoreDrawing->GetState() == kButtonDown);
3391 fitOpts.Nograph = (fNoDrawing->GetState() == kButtonDown);
3392 fitOpts.Plus = (fAdd2FuncList->GetState() == kButtonDown);
3393 fitOpts.Gradient = (fUseGradient->GetState() == kButtonDown);
3394 fitOpts.Quiet = ( fOptQuiet->GetState() == kButtonDown );
3395 fitOpts.Verbose = ( fOptVerbose->GetState() == kButtonDown );
3396
3397 if ( !(fType != kObjectGraph) && (fEnableRobust->GetState() == kButtonDown) )
3398 {
3399 fitOpts.Robust = 1;
3400 fitOpts.hRobust = fRobustValue->GetNumber();
3401 }
3402
3403 drawOpts = GetDrawOption();
3404
3405 if ( fLibMinuit->GetState() == kButtonDown )
3406 minOpts.SetMinimizerType ( "Minuit");
3407 else if ( fLibMinuit2->GetState() == kButtonDown)
3408 minOpts.SetMinimizerType ( "Minuit2" );
3409 else if ( fLibFumili->GetState() == kButtonDown )
3410 minOpts.SetMinimizerType ("Fumili" );
3411 else if ( fLibGSL->GetState() == kButtonDown )
3412 minOpts.SetMinimizerType ("GSLMultiMin" );
3413
3414 if ( fMinMethodList->GetSelected() == kFP_MIGRAD )
3415 minOpts.SetMinimizerAlgorithm( "Migrad" );
3416 else if ( fMinMethodList->GetSelected() == kFP_FUMILI)
3417 if ( fLibMinuit2->GetState() == kButtonDown )
3418 minOpts.SetMinimizerAlgorithm( "Fumili2" );
3419 else
3420 minOpts.SetMinimizerAlgorithm( "Fumili" );
3421 else if ( fMinMethodList->GetSelected() == kFP_SIMPLX )
3422 minOpts.SetMinimizerAlgorithm( "Simplex" );
3423 else if ( fMinMethodList->GetSelected() == kFP_SCAN )
3424 minOpts.SetMinimizerAlgorithm( "Scan" );
3425 else if ( fMinMethodList->GetSelected() == kFP_COMBINATION )
3426 minOpts.SetMinimizerAlgorithm( "Minimize" );
3427 else if ( fMinMethodList->GetSelected() == kFP_GSLFR )
3428 minOpts.SetMinimizerAlgorithm( "conjugatefr" );
3429 else if ( fMinMethodList->GetSelected() == kFP_GSLPR )
3430 minOpts.SetMinimizerAlgorithm( "conjugatepr" );
3431 else if ( fMinMethodList->GetSelected() == kFP_BFGS )
3432 minOpts.SetMinimizerAlgorithm( "bfgs" );
3433 else if ( fMinMethodList->GetSelected() == kFP_BFGS2 )
3434 minOpts.SetMinimizerAlgorithm( "bfgs2" );
3435 else if ( fMinMethodList->GetSelected() == kFP_GSLLM ) {
3436 minOpts.SetMinimizerType ("GSLMultiFit" );
3437 minOpts.SetMinimizerAlgorithm( "" );
3438 } else if ( fMinMethodList->GetSelected() == kFP_GSLSA) {
3439 minOpts.SetMinimizerType ("GSLSimAn" );
3440 minOpts.SetMinimizerAlgorithm( "" );
3441 } else if ( fMinMethodList->GetSelected() == kFP_TMVAGA) {
3442 minOpts.SetMinimizerType ("Geneti2c" );
3443 minOpts.SetMinimizerAlgorithm( "" );
3444 } else if ( fMinMethodList->GetSelected() == kFP_GALIB) {
3445 minOpts.SetMinimizerType ("GAlibMin" );
3446 minOpts.SetMinimizerAlgorithm( "" );
3447 }
3448
3449 minOpts.SetErrorDef ( fErrorScale->GetNumber() );
3450 minOpts.SetTolerance( fTolerance->GetNumber() );
3451 minOpts.SetMaxIterations(fIterations->GetIntNumber());
3452 minOpts.SetMaxFunctionCalls(fIterations->GetIntNumber());
3453}
3454
3456{
3457 // Set the state of some input widgets depending on whether the fit
3458 // function can be defined by text or if it is an existing one.
3459 if ( state )
3460 {
3461 fEnteredFunc-> SetState(kTRUE);
3462 fAdd -> SetState(kButtonUp, kFALSE);
3463 fNormAdd -> SetState(kButtonUp, kFALSE);
3464 fConv -> SetState(kButtonUp, kFALSE);
3465 fNone -> SetState(kButtonDown,kFALSE); // fNone::State is the one used as reference
3466 }
3467 else
3468 {
3469 fEnteredFunc-> SetState(kFALSE);
3470 fAdd -> SetState(kButtonDisabled, kFALSE);
3471 fNormAdd -> SetState(kButtonDisabled, kFALSE);
3472 fConv -> SetState(kButtonDisabled, kFALSE);
3473 fNone -> SetState(kButtonDisabled, kFALSE);
3474 }
3475}
3476
3478{
3479 // Return the ranges selected by the sliders.
3480
3481 // It's not working for trees as they don't have TAxis.
3482 if ( fType == kObjectTree ) return;
3483
3484 if ( fType != kObjectTree ) {
3485 Int_t ixmin = (Int_t)(fSliderX->GetMinPosition());
3486 Int_t ixmax = (Int_t)(fSliderX->GetMaxPosition());
3487 Double_t xmin = fXaxis->GetBinLowEdge(ixmin);
3488 Double_t xmax = fXaxis->GetBinUpEdge(ixmax);
3489 drange.AddRange(0,xmin, xmax);
3490 }
3491
3492 if ( fDim > 1 ) {
3493 assert(fYaxis);
3494 Int_t iymin = (Int_t)(fSliderY->GetMinPosition());
3495 Int_t iymax = (Int_t)(fSliderY->GetMaxPosition());
3496 Double_t ymin = fYaxis->GetBinLowEdge(iymin);
3497 Double_t ymax = fYaxis->GetBinUpEdge(iymax);
3498 drange.AddRange(1,ymin, ymax);
3499 }
3500 if ( fDim > 2 ) {
3501 assert(fZaxis);
3502 Int_t izmin = (Int_t)(fSliderZ->GetMinPosition());
3503 Int_t izmax = (Int_t)(fSliderZ->GetMaxPosition());
3504 Double_t zmin = fZaxis->GetBinLowEdge(izmin);
3505 Double_t zmax = fZaxis->GetBinUpEdge(izmax);
3506 drange.AddRange(2,zmin, zmax);
3507 }
3508}
3509
3511{
3512 // Get the list of functions previously used in the fitobject.
3513
3514 TList *listOfFunctions = 0;
3515 if ( fFitObject ) {
3516 switch (fType) {
3517
3518 case kObjectHisto:
3519 listOfFunctions = ((TH1 *)fFitObject)->GetListOfFunctions();
3520 break;
3521
3522 case kObjectGraph:
3523 listOfFunctions = ((TGraph *)fFitObject)->GetListOfFunctions();
3524 break;
3525
3526 case kObjectMultiGraph:
3527 listOfFunctions = ((TMultiGraph *)fFitObject)->GetListOfFunctions();
3528 break;
3529
3530 case kObjectGraph2D:
3531 listOfFunctions = ((TGraph2D *)fFitObject)->GetListOfFunctions();
3532 break;
3533
3534 case kObjectHStack:
3535 case kObjectTree:
3536 default:
3537 break;
3538 }
3539 }
3540 return listOfFunctions;
3541}
3542
3544{
3545 // Looks for all the functions registered in the current ROOT
3546 // session.
3547
3548 // First, clean the copies stored in fSystemFunc
3549 for (auto func : fSystemFuncs)
3550 delete func;
3551
3552 fSystemFuncs.clear();
3553
3554 // Be carefull not to store functions that will be in the
3555 // predefined section
3556 const unsigned int nfuncs = 16;
3557 const char* fnames[nfuncs] = { "gaus" , "gausn", "expo", "landau",
3558 "landaun", "pol0", "pol1", "pol2",
3559 "pol3", "pol4", "pol5", "pol6",
3560 "pol7", "pol8", "pol9", "user"
3561 };
3562
3563 // No go through all the objects registered in gROOT
3564 TIter functionsIter(gROOT->GetListOfFunctions());
3565 TObject* obj;
3566 while( ( obj = (TObject*) functionsIter() ) ) {
3567 // And if they are TF1s
3568 if ( TF1* func = dynamic_cast<TF1*>(obj) ) {
3569 bool addFunction = true;
3570 // And they are not already registered in fSystemFunc
3571 for ( unsigned int i = 0; i < nfuncs; ++i ) {
3572 if ( strcmp( func->GetName(), fnames[i] ) == 0 ) {
3573 addFunction = false;
3574 break;
3575 }
3576 }
3577 // Add them.
3578 if ( addFunction )
3579 fSystemFuncs.emplace_back( copyTF1(func) );
3580 }
3581 }
3582}
3583
3585{
3586 // This function returns a TList with all the functions used in the
3587 // FitPanel to fit a given object. If the object passed is NULL,
3588 // then the object used is the currently selected one. It is
3589 // important to notice that the FitPanel is still the owner of
3590 // those functions. This means that the user SHOULD NOT delete any
3591 // of these functions, as the FitPanel will do so in the
3592 // destructor.
3593
3594 if (!obj) obj = fFitObject;
3595
3596 TList *retList = new TList();
3597
3598 std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(obj);
3599 for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
3600 retList->Add(it->second);
3601 }
3602
3603 return retList;
3604}
3605
3607{
3608 // Get the fit function selected or declared in the fiteditor
3609
3610 TF1 *fitFunc = 0;
3611 // If the function is not editable ==> it means it is registered in
3612 // gROOT
3613 if ( fNone->GetState() == kButtonDisabled )
3614 {
3615 // So we find it
3616 TF1* tmpF1 = FindFunction();
3617 // And if we don't find it, then it means there is something wrong!
3618 if ( tmpF1 == 0 )
3619 {
3620 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
3621 "Error...", "1) Verify the entered function string!",
3622 kMBIconStop,kMBOk, 0);
3623 return 0;
3624 }
3625
3626 // Now we make a copy that will be used temporary. The caller of
3627 // the function should delete the returned function.
3628 fitFunc = (TF1*)tmpF1->IsA()->New();
3629 tmpF1->Copy(*fitFunc);
3630 // Copy the parameters of the function, if and only if the
3631 // parameters stored does not correspond with the ones of these
3632 // functions. Perhaps the user has already called
3633 // DoSetParameters. There is no way to know whether the
3634 // parameters have been modified, so we check the size of
3635 // fFuncPars against number of parameters.
3636 if ( int(fFuncPars.size()) != tmpF1->GetNpar() )
3637 {
3638 fitFunc->SetParameters(tmpF1->GetParameters());
3639 GetParameters(fFuncPars, fitFunc);
3640 } else {
3641 SetParameters(fFuncPars, fitFunc);
3642 }
3643 }
3644
3645 // If, we have no function at this point, it means that is is
3646 // described in fEnteredFunc, so we create it from scratch.
3647 if ( fitFunc == 0 )
3648 {
3649 ROOT::Fit::DataRange drange;
3650 GetRanges(drange);
3651 double xmin, xmax, ymin, ymax, zmin, zmax;
3652 drange.GetRange(xmin, xmax, ymin, ymax, zmin, zmax);
3653
3654 // Depending of course on the number of dimensions the object
3655 // has. These commands will raise an error message if the user
3656 // has not defined the function properly
3657 if ( fDim == 1 || fDim == 0 )
3658 {
3659
3660 fitFunc = new TF1("PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax );
3661 //std::cout << "GetFitFunction - created function PrevFitTMP " << fEnteredFunc->GetText() << " " << fitFunc << std::endl;
3662 if (fNormAdd->IsOn())
3663 {
3664 if (fSumFunc) delete fSumFunc;
3665 fSumFunc = new TF1NormSum(fEnteredFunc->GetText(), xmin, xmax);
3666 fitFunc = new TF1("PrevFitTMP", *fSumFunc, xmin, xmax, fSumFunc->GetNpar());
3667 for (int i = 0; i < fitFunc->GetNpar(); ++i) fitFunc->SetParName(i, fSumFunc->GetParName(i) );
3668 //std::cout << "create fit normalized function " << fSumFunc << " fitfunc " << fitFunc << std::endl;
3669 }
3670
3671 if (fConv -> IsOn())
3672 {
3673 if (fConvFunc) delete fConvFunc;
3674 fConvFunc = new TF1Convolution(fEnteredFunc->GetText());
3675 fitFunc = new TF1("PrevFitTMP", *fConvFunc, xmin, xmax, fConvFunc->GetNpar());
3676 for (int i = 0; i < fitFunc->GetNpar(); ++i) fitFunc->SetParName(i, fConvFunc->GetParName(i) );
3677 //std::cout << "create fit convolution function " << fSumFunc << " fitfunc " << fitFunc << std::endl;
3678 }
3679 }
3680 else if ( fDim == 2 ) {
3681 fitFunc = new TF2("PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax, ymin, ymax );
3682 }
3683 else if ( fDim == 3 ) {
3684 fitFunc = new TF3("PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax, ymin, ymax, zmin, zmax );
3685 }
3686
3687 // if the function is not a C defined
3688 if ( fNone->GetState() != kButtonDisabled )
3689 {
3690 // and the formulas are the same
3691 TF1* tmpF1 = FindFunction();
3692// if (tmpF1)
3693 //std::cout << "GetFitFunction: found existing function " << tmpF1 << " " << tmpF1->GetName() << " " << tmpF1->GetExpFormula() << std::endl;
3694// else
3695 //std::cout << "GetFitFunction: - no existing function found " << std::endl;
3696 if ( tmpF1 != 0 && fitFunc != 0 &&
3697 strcmp(tmpF1->GetExpFormula(), fEnteredFunc->GetText()) == 0 ) {
3698 // copy everything from the founction available in gROOT
3699 //std::cout << "GetFitFunction: copying tmp function in PrevFitTMP " << tmpF1->GetName() << " "
3700 // << tmpF1->GetExpFormula() << std::endl;
3701 tmpF1->Copy(*fitFunc);
3702 if ( int(fFuncPars.size()) != tmpF1->GetNpar() )
3703 {
3704 GetParameters(fFuncPars, fitFunc);
3705 }
3706 }
3707 }
3708 }
3709
3710 return fitFunc;
3711}
@ kButton1Down
Definition Buttons.h:17
@ kVerticalFrame
Definition GuiTypes.h:382
@ kFixedWidth
Definition GuiTypes.h:388
@ kFitWidth
Definition GuiTypes.h:387
@ kHorizontalFrame
Definition GuiTypes.h:383
@ kFixedSize
Definition GuiTypes.h:391
@ kWatch
Definition GuiTypes.h:376
@ kPointer
Definition GuiTypes.h:376
ULong_t Pixel_t
Pixel value.
Definition GuiTypes.h:41
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
char * ret
Definition Rotated.cxx:221
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
Definition RtypesCore.h:60
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
float Float_t
Float 4 bytes (float).
Definition RtypesCore.h:71
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char).
Definition RtypesCore.h:80
const Bool_t kIterForward
Definition TCollection.h:42
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
#define gDirectory
Definition TDirectory.h:385
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
TF1 * copyTF1(TF1 *f)
Copies f into a new TF1 to be stored in the fitpanel with it's own ownership.
void GetParameters(TFitEditor::FuncParams_t &pars, TF1 *func)
Stores the parameters of the given function into pars.
void InitParameters(TF1 *func, FitObject *fitobj)
Parameter initialization for the function.
void GetTreeVarsAndCuts(TGComboBox *dataSet, TString &variablesStr, TString &cutsStr)
Splits the entry in fDataSet to get the selected variables and cuts from the text.
void SetParameters(TFitEditor::FuncParams_t &pars, TF1 *func)
Restore the parameters from pars into the function.
void SearchCanvases(TSeqCollection *canvases, std::vector< TObject * > &objects)
std::multimap< TObject *, TF1 * > FitFuncMap_t
@ kObjectMultiGraph
Definition TFitEditor.h:33
@ kObjectGraph
Definition TFitEditor.h:29
@ kObjectHStack
Definition TFitEditor.h:31
@ kObjectHisto
Definition TFitEditor.h:28
@ kObjectGraph2D
Definition TFitEditor.h:30
@ kObjectTree
Definition TFitEditor.h:32
@ kButtonDown
Definition TGButton.h:54
@ kButtonDisabled
Definition TGButton.h:56
@ kButtonUp
Definition TGButton.h:53
@ kButtonEngaged
Definition TGButton.h:55
#define gClient
Definition TGClient.h:157
@ kDoubleScaleBoth
@ kMWMDecorResizeH
Definition TGFrame.h:65
@ kMWMFuncAll
Definition TGFrame.h:49
@ kMWMFuncResize
Definition TGFrame.h:50
@ kMWMDecorMaximize
Definition TGFrame.h:69
@ kMWMDecorMinimize
Definition TGFrame.h:68
@ kMWMDecorMenu
Definition TGFrame.h:67
@ kMWMDecorAll
Definition TGFrame.h:63
@ kMWMFuncMaximize
Definition TGFrame.h:53
@ kMWMInputModeless
Definition TGFrame.h:57
@ kMWMFuncMinimize
Definition TGFrame.h:52
@ kDeepCleanup
Definition TGFrame.h:42
@ kLHintsRight
Definition TGLayout.h:26
@ kLHintsExpandY
Definition TGLayout.h:31
@ kLHintsLeft
Definition TGLayout.h:24
@ kLHintsCenterY
Definition TGLayout.h:28
@ kLHintsNormal
Definition TGLayout.h:32
@ kLHintsBottom
Definition TGLayout.h:29
@ kLHintsTop
Definition TGLayout.h:27
@ kLHintsExpandX
Definition TGLayout.h:30
@ kMBOk
Definition TGMsgBox.h:33
@ kMBIconAsterisk
Definition TGMsgBox.h:25
@ kMBIconStop
Definition TGMsgBox.h:22
@ kTextLeft
Definition TGWidget.h:23
char name[80]
Definition TGX11.cxx:148
float xmin
float ymin
float xmax
float ymax
externTPluginManager * gPluginMgr
externvoid * gTQSender
Definition TQObject.h:46
#define gROOT
Definition TROOT.h:417
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2496
#define gPad
#define gVirtualX
Definition TVirtualX.h:375
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition BinData.h:52
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition DataRange.h:35
void AddRange(unsigned int icoord, double xmin, double xmax)
add a range [xmin,xmax] for the new coordinate icoord Adding a range does not delete existing one,...
Definition DataRange.cxx:94
void GetRange(unsigned int irange, unsigned int icoord, double &xmin, double &xmax) const
get the i-th range for given coordinate.
Definition DataRange.h:104
unsigned int Size() const
return number of fit points
Definition FitData.h:292
const double * Coords(unsigned int ipoint) const
return a pointer to the coordinates data for the given fit point
Definition FitData.h:235
Class describing the un-binned data sets (just x coordinates values) of any dimensions.
Definition UnBinData.h:46
void SetMaxFunctionCalls(unsigned int maxfcn)
set maximum of function calls
void SetMaxIterations(unsigned int maxiter)
set maximum iterations (one iteration can have many function calls)
void SetMinimizerType(const char *type)
set minimizer type
static const std::string & DefaultMinimizerType()
void SetErrorDef(double err)
set error def
void SetMinimizerAlgorithm(const char *type)
set minimizer algorithm
void SetTolerance(double tol)
set the tolerance
Allows to create advanced graphics from the last fit made in the fitpanel.
The Canvas class.
Definition TCanvas.h:23
Int_t GetWindowTopX()
Returns current top x position of window on screen.
Definition TCanvas.cxx:1204
Int_t GetWindowTopY()
Returns current top y position of window on screen.
Definition TCanvas.cxx:1215
virtual void Selected(TVirtualPad *pad, TObject *obj, Int_t event)
Emit Selected() signal.
Definition TCanvas.cxx:1632
UInt_t GetWindowWidth() const
Definition TCanvas.h:165
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5048
Class wrapping convolution of two functions.
Class adding two functions: c1*f1+c2*f2.
Definition TF1NormSum.h:19
Definition TF1.h:182
virtual Int_t GetNumber() const
Definition TF1.h:463
static TClass * Class()
virtual void Save(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax)
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
virtual Int_t GetNpar() const
Definition TF1.h:446
virtual TString GetExpFormula(Option_t *option="") const
Definition TF1.h:426
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
virtual void SetParent(TObject *p=nullptr)
Definition TF1.h:647
virtual Double_t * GetParameters() const
Definition TF1.h:485
void Copy(TObject &f1) const override
Copy this to obj.
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
virtual void SetRange(Double_t xmin, Double_t xmax)
void Draw(Option_t *option="") override
Default Draw method for all objects.
virtual Bool_t IsValid() const
virtual void SetParameters(const Double_t *params)
Definition TF1.h:618
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:608
virtual void SetParName(Int_t ipar, const char *name)
TClass * IsA() const override
Definition TF1.h:694
virtual Double_t GetParameter(Int_t ipar) const
Definition TF1.h:477
virtual Bool_t AddToGlobalList(Bool_t on=kTRUE)
Definition TF2.h:29
void Save(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax) override
void SetRange(Double_t xmin, Double_t xmax) override
Definition TF2.h:133
Definition TF3.h:28
void SetRange(Double_t xmin, Double_t xmax) override
Definition TF3.h:131
Allows to perform, explore and compare various fits.
Definition TFitEditor.h:54
TList * GetListOfFittingFunctions(TObject *obj=nullptr)
TGCheckButton * fBestErrors
switch on/off option 'improve errors'
Definition TFitEditor.h:81
TF1 * FindFunction()
This method looks among the functions stored by the fitpanel, the one that is currently selected in t...
TGDoubleHSlider * fSliderX
slider to set fit range along x-axis
Definition TFitEditor.h:95
static TFitEditor * GetInstance(TVirtualPad *pad=nullptr, TObject *obj=nullptr)
Static method - opens the fit panel.
TFitEditor(const TFitEditor &)
TGComboBox * fMinMethodList
Definition TFitEditor.h:138
void CloseWindow() override
Close fit panel window.
TGTextButton * fSetParam
open set parameters dialog
Definition TFitEditor.h:79
void CreateGeneralTab()
Create 'General' tab.
virtual void DoUpdate()
Easy here!
TGLayoutHints * fLayoutNormAdd
layout hints of fNOrmAdd radio button
Definition TFitEditor.h:77
TGNumberEntry * fSliderXMax
entry to set the maximum in the range
Definition TFitEditor.h:96
virtual void DoConvolution(Bool_t on)
Slot connected to addition of predefined functions.
TGNumberEntry * fSliderXMin
entry to set the minumum in the range
Definition TFitEditor.h:97
virtual void SetFitObject(TVirtualPad *pad, TObject *obj, Int_t event)
Slot called when the user clicks on an object inside a canvas.
virtual void DoEnteredFunction()
Slot connected to entered function in text entry.
virtual void DoNormAddition(Bool_t on)
Slot connected to addition of predefined functions.
virtual void DoPrintOpt(Bool_t on)
Slot connected to print option settings.
std::vector< TF1 * > fSystemFuncs
Definition TFitEditor.h:131
TGCheckButton * fDrawSame
switch on/off fit function drawing
Definition TFitEditor.h:93
TGRadioButton * fLibMinuit
Definition TFitEditor.h:133
TGRadioButton * fConv
set convolution mode
Definition TFitEditor.h:74
TVirtualPad * fParentPad
pad containing the object
Definition TFitEditor.h:110
TGRadioButton * fOptDefault
set default printing mode
Definition TFitEditor.h:107
TGCheckButton * fLinearFit
switch on/off linear fit option
Definition TFitEditor.h:89
TGRadioButton * fLibMinuit2
Definition TFitEditor.h:134
virtual void DoMinMethod(Int_t)
Set selected minimization method in use.
TF1 * HasFitFunction()
Look in the list of function for TF1.
void UpdateGUI()
Set the fit panel GUI according to the selected object.
TGCheckButton * fUseRange
switch on/off option 'use function range'
Definition TFitEditor.h:82
virtual void DoSliderXMoved()
Slot connected to range settings on x-axis.
TAxis * fYaxis
y-axis
Definition TFitEditor.h:115
TGTextButton * fDrawAdvanced
opens a dialog for advanced draw options
Definition TFitEditor.h:94
TGComboBox * fTypeFit
contains the types of functions to be selected
Definition TFitEditor.h:67
virtual void DoReset()
Reset all fit parameters.
TGNumberEntryField * fTolerance
Definition TFitEditor.h:140
TGCheckButton * fNoDrawing
switch on/off 'no drawing' option
Definition TFitEditor.h:92
TF1 * GetFitFunction()
TGHorizontalFrame * fSliderZParent
parent of fSliderZ
Definition TFitEditor.h:104
virtual void DoSetParameters()
Open set parameters dialog.
TGCompositeFrame * fMinimization
minimization tab
Definition TFitEditor.h:60
TGTab * fTab
tab widget holding the editor
Definition TFitEditor.h:57
virtual void DoLinearFit()
Slot connected to linear fit settings.
void FillFunctionList(Int_t selected=-1)
Fills the list of functions depending on the type of fit selected.
virtual void Show(TVirtualPad *pad, TObject *obj)
Show the fit panel (possible only via context menu).
virtual void DoNumericSliderYChanged()
syncronize the numeric slider with the graphical one.
virtual void DoClose()
Close the fit panel.
TF1NormSum * fSumFunc
! TF1NormSum object
Definition TFitEditor.h:117
TGComboBox * fMethodList
contains method list
Definition TFitEditor.h:88
TGDoubleHSlider * fSliderY
slider to set fit range along y-axis
Definition TFitEditor.h:98
void ShowObjectName(TObject *obj)
Show object name on the top.
static TFitEditor * fgFitDialog
Definition TFitEditor.h:147
TList * GetFitObjectListOfFunctions()
virtual void DoAdvancedOptions()
Slot connected to advanced option button (opens a dialog).
TGRadioButton * fLibFumili
Definition TFitEditor.h:135
virtual void DoDataSet(Int_t sel)
Selects the data set to be fitted.
TGRadioButton * fAdd
set addition mode
Definition TFitEditor.h:72
TGComboBox * BuildMethodList(TGFrame *parent, Int_t id)
Create method list in a combo box.
void CreateMinimizationTab()
Create 'Minimization' tab.
TGRadioButton * fLibGenetics
Definition TFitEditor.h:137
TGCheckButton * fImproveResults
switch on/off option 'improve fit results'
Definition TFitEditor.h:86
TGComboBox * fFuncList
contains function list
Definition TFitEditor.h:68
TF1Convolution * fConvFunc
! TF1Convolution object
Definition TFitEditor.h:118
TGCheckButton * fUseGradient
switch on/off option 'use gradient'
Definition TFitEditor.h:84
TGRadioButton * fNormAdd
set normalized addition mode
Definition TFitEditor.h:73
virtual void SetCanvas(TCanvas *c)
Connect to another canvas.
EObjectType fType
object type info
Definition TFitEditor.h:112
TGNumberEntryField * fIterations
Definition TFitEditor.h:141
TGCompositeFrame * fTabContainer
main tab container
Definition TFitEditor.h:58
virtual void DoFunction(Int_t sel)
Slot connected to predefined fit function settings.
virtual void DoUseFuncRange()
TGComboBox * fDataSet
contains list of data set to be fitted
Definition TFitEditor.h:66
virtual void ConnectSlots()
Connect GUI signals to fit panel slots.
virtual void DoFit()
Perform a fit with current parameters' settings.
TAxis * fZaxis
z-axis
Definition TFitEditor.h:116
TGRadioButton * fOptVerbose
set printing mode to 'Verbose'
Definition TFitEditor.h:108
virtual void SetFunction(const char *function)
Set the function to be used in performed fit.
virtual void Terminate()
Called to delete the fit panel.
TGTextButton * fUserButton
opens a dialog for user-defined fit method
Definition TFitEditor.h:70
~TFitEditor() override
Fit editor destructor.
TGDoubleHSlider * fSliderZ
slider to set fit range along z-axis
Definition TFitEditor.h:101
TGTextButton * fFitButton
performs fitting
Definition TFitEditor.h:62
virtual void DoMaxIterations()
Set the maximum number of iterations.
virtual void DoLibrary(Bool_t on)
Set selected minimization library in use.
void FillDataSetList()
Create a combo box with all the possible objects to be fitted.
virtual void DoEmptyBinsAllWeights1()
Slot connected to 'include emtry bins and forse all weights to 1' setting.
virtual void DoSliderYMoved()
Slot connected to range settings on y-axis.
void RetrieveOptions(Foption_t &, TString &, ROOT::Math::MinimizerOptions &, Int_t)
Retrieve the fitting options from all the widgets.
std::vector< FuncParamData_t > fFuncPars
Definition TFitEditor.h:128
TGHorizontalFrame * fSliderYParent
parent of fSliderY
Definition TFitEditor.h:103
TGCheckButton * fNoChi2
switch on/off option 'No Chi-square'
Definition TFitEditor.h:90
virtual void DoNoStoreDrawing()
Slot connected to 'no storing, no drawing' settings.
void MakeTitle(TGCompositeFrame *parent, const char *title)
Create section title in the GUI.
virtual void DoNoSelection()
Slot called when users close a TCanvas or when the user select no object.
TGTextButton * fUpdateButton
updates data from gROOT and gDirectory
Definition TFitEditor.h:61
TGTextEntry * fEnteredFunc
contains user function file name
Definition TFitEditor.h:69
TGCheckButton * fIntegral
switch on/off option 'integral'
Definition TFitEditor.h:80
virtual void DoAllWeights1()
Slot connected to 'set all weights to 1' setting.
Bool_t SetObjectType(TObject *obj)
Check whether the object suitable for fitting and set its type, dimension and method combo box accord...
virtual void Hide()
Hide the fit panel and set it to non-active state.
TGNumberEntryField * fErrorScale
Definition TFitEditor.h:139
void SetEditable(Bool_t) override
Option_t * GetDrawOption() const override
Get draw options of the selected object.
TAxis * fXaxis
x-axis
Definition TFitEditor.h:114
std::vector< FuncParamData_t > FuncParams_t
Definition TFitEditor.h:239
TGLayoutHints * fLayoutAdd
layout hints of fAdd radio button
Definition TFitEditor.h:76
TGHorizontalFrame * fSliderXParent
parent of fSliderX
Definition TFitEditor.h:102
void ProcessTreeInput(TObject *objSelected, Int_t selected, TString variables, TString cuts)
TGCheckButton * fEnableRobust
switch on/off robust option
Definition TFitEditor.h:105
void DrawSelection(bool restore=false)
Draws the square around the object showing where the limits for fitting are.
TGCheckButton * fEmptyBinsWghts1
switch on/off option 'include empry bins'
Definition TFitEditor.h:87
virtual void DoSliderZMoved()
Slot connected to range settings on z-axis.
Int_t fDim
object dimension
Definition TFitEditor.h:113
TGNumberEntry * fSliderYMin
entry to set the minumum in the range
Definition TFitEditor.h:100
void GetRanges(ROOT::Fit::DataRange &)
std::multimap< TObject *, TF1 * > fPrevFit
Definition TFitEditor.h:130
TGNumberEntry * fRobustValue
contains robust value for linear fit
Definition TFitEditor.h:106
TGNumberEntry * fSliderYMax
entry to set the maximum in the range
Definition TFitEditor.h:99
virtual void DoNoChi2()
Slot connected to 'no chi2' option settings.
TGCheckButton * fAdd2FuncList
switch on/off option 'add to list'
Definition TFitEditor.h:83
TGCompositeFrame * fGeneral
general tab
Definition TFitEditor.h:59
virtual void DisconnectSlots()
Disconnect GUI signals from fit panel slots.
void GetFunctionsFromSystem()
TGRadioButton * fOptQuiet
set printing mode to 'Quiet'
Definition TFitEditor.h:109
void FillMinMethodList(Int_t selected=-1)
Fills the list of methods depending on the minimization library selected.
TGCheckButton * fNoStoreDrawing
switch on/off 'no store/drwing' option
Definition TFitEditor.h:91
TGCheckButton * fAllWeights1
switch on/off option 'all weights=1'
Definition TFitEditor.h:85
TGRadioButton * fNone
set no operation mode
Definition TFitEditor.h:71
TGLayoutHints * fLayoutConv
layout hints of fConv radio button
Definition TFitEditor.h:78
TGTextButton * fResetButton
resets fit parameters
Definition TFitEditor.h:63
void CreateFunctionGroup()
Creates the Frame that contains oll the information about the function.
TGLayoutHints * fLayoutNone
layout hints of fNone radio button
Definition TFitEditor.h:75
TGLabel * fSelLabel
contains selected fit function
Definition TFitEditor.h:65
TGRadioButton * fLibGSL
Definition TFitEditor.h:136
Int_t CheckFunctionString(const char *str)
Check entered function string.
void RecursiveRemove(TObject *obj) override
When obj is deleted, clear fFitObject if fFitObject = obj.
TObject * fFitObject
selected object to fit
Definition TFitEditor.h:111
virtual void DoRobustFit()
Slot connected to 'robust fitting' option settings.
TGTextButton * fCloseButton
close the fit panel
Definition TFitEditor.h:64
virtual void DoAddition(Bool_t on)
Slot connected to addition of predefined functions.
Bool_t fChangedParams
Definition TFitEditor.h:145
TGStatusBar * fStatusBar
Definition TFitEditor.h:143
virtual void DoUserDialog()
Open a dialog for getting a user defined method.
virtual void DoNumericSliderXChanged()
Sincronize the numeric sliders with the graphical one.
Create a dialog for fit function parameter settings.
The Formula class.
Definition TFormula.h:89
Int_t GetNpar() const
Definition TFormula.h:262
A button abstract base class.
Definition TGButton.h:68
Selects different options.
Definition TGButton.h:264
A combobox (also known as a drop down listbox) allows the selection of one item out of a list of item...
Definition TGComboBox.h:47
virtual Int_t GetSelected() const
Definition TGComboBox.h:114
virtual TGListBox * GetListBox() const
Definition TGComboBox.h:110
TGDimension GetDefaultSize() const override
std::cout << fWidth << "x" << fHeight << std::endl;
Definition TGFrame.h:318
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=nullptr)
Add frame to the composite frame using the specified layout hints.
Definition TGFrame.cxx:1109
Int_t GetState(TGFrame *f) const
Get state of sub frame.
Definition TGFrame.cxx:1210
virtual void Cleanup()
Cleanup and delete all objects contained in this composite frame.
Definition TGFrame.cxx:959
void MapSubwindows() override
Map all sub windows that are part of the composite frame.
Definition TGFrame.cxx:1156
TGCompositeFrame(const TGCompositeFrame &)=delete
void Layout() override
Layout the elements of the composite frame.
Definition TGFrame.cxx:1249
void SetCleanup(Int_t mode=kLocalCleanup) override
Turn on automatic cleanup of child frames in dtor.
Definition TGFrame.cxx:1064
void ChangeOptions(UInt_t options) override
Change composite frame options. Options is an OR of the EFrameTypes.
Definition TGFrame.cxx:1035
Dragging the slider will generate the event:
void MoveResize(Int_t x, Int_t y, UInt_t w=0, UInt_t h=0) override
Move and/or resize the frame.
Definition TGFrame.cxx:621
void Resize(UInt_t w=0, UInt_t h=0) override
Resize the frame.
Definition TGFrame.cxx:597
TGFrame(const TGFrame &)=delete
void MapWindow() override
map window
Definition TGFrame.h:206
virtual UInt_t GetOptions() const
Definition TGFrame.h:199
UInt_t GetWidth() const
Definition TGFrame.h:226
A composite frame with a border and a title.
Definition TGFrame.h:532
Organizes TGButton widgets in a group with one horizontal row.
A horizontal 3D line is a line that typically separates a toolbar from the menubar.
Definition TG3DLine.h:18
A composite frame that layout their children in horizontal way.
Definition TGFrame.h:387
Basic listbox entries.
Definition TGListBox.h:24
Int_t EntryId() const
Definition TGListBox.h:40
This class handles GUI labels.
Definition TGLabel.h:24
This class describes layout hints used by the layout classes.
Definition TGLayout.h:50
A listbox is a box, possibly with scrollbar, containing entries.
Definition TGListBox.h:221
virtual Int_t GetNumberOfEntries() const
Definition TGListBox.h:263
void Resize(UInt_t w, UInt_t h) override
Resize the listbox widget.
TGMainFrame(const TGMainFrame &)=delete
void SetClassHints(const char *className, const char *resourceName)
Set the windows class and resource name.
Definition TGFrame.cxx:1850
void SetIconName(const char *name)
Set window icon name. This is typically done via the window manager.
Definition TGFrame.cxx:1793
void SetWMSize(UInt_t w, UInt_t h)
Give the window manager a window size hint.
Definition TGFrame.cxx:1885
void SetWMPosition(Int_t x, Int_t y)
Give the window manager a window position hint.
Definition TGFrame.cxx:1873
void SetWindowName(const char *name=nullptr) override
Set window name. This is typically done via the window manager.
Definition TGFrame.cxx:1780
void SetMWMHints(UInt_t value, UInt_t funcs, UInt_t input)
Set decoration style for MWM-compatible wm (mwm, ncdwm, fvwm?).
Definition TGFrame.cxx:1860
void SetWMSizeHints(UInt_t wmin, UInt_t hmin, UInt_t wmax, UInt_t hmax, UInt_t winc, UInt_t hinc)
Give the window manager minimum and maximum size hints.
Definition TGFrame.cxx:1898
TGNumberEntry is a number entry input widget with up/down buttons.
@ kNEAPositive
Positive number.
@ kNEAAnyNumber
Attributes of number entry field.
@ kNESReal
Real number.
@ kNESInteger
Style of number entry field.
@ kNESRealTwo
Fixed fraction real, two digit.
@ kNELNoLimits
Limit selection of number entry field.
@ kNELLimitMinMax
Both lower and upper limits.
TGClient * fClient
Connection to display server.
Definition TGObject.h:25
Handle_t GetId() const
Definition TGObject.h:41
Selects different options.
Definition TGButton.h:321
Provides a StatusBar widget.
Definition TGStatusBar.h:21
const char * GetString() const
Definition TGString.h:30
A tab widget contains a set of composite frames each with a little tab with a name (like a set of fol...
Definition TGTab.h:46
A text buffer is used in several widgets, like TGTextEntry, TGFileDialog, etc.
Yield an action as soon as it is clicked.
Definition TGButton.h:142
A TGTextEntry is a one line text input widget.
Definition TGTextEntry.h:24
Text string listbox entries.
Definition TGListBox.h:48
const TGString * GetText() const
Definition TGListBox.h:79
const char * GetTitle() const override
Returns title of object.
Definition TGListBox.h:81
A composite frame that layout their children in vertical way.
Definition TGFrame.h:376
Int_t WidgetId() const
Definition TGWidget.h:68
virtual const TGWindow * GetMainFrame() const
Returns top level main frame.
Definition TGWindow.cxx:150
const char * GetName() const override
Return unique name, used in SavePrimitive methods.
Definition TGWindow.cxx:334
static TClass * Class()
static TClass * Class()
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
TAxis * GetZaxis()
Definition TH1.h:573
static TClass * Class()
virtual Int_t GetDimension() const
Definition TH1.h:527
TAxis * GetXaxis()
Definition TH1.h:571
TAxis * GetYaxis()
Definition TH1.h:572
static TClass * Class()
Iterator of linked list.
Definition TList.h:196
Option_t * GetOption() const override
Returns the object option stored in the list.
Definition TList.cxx:1274
A doubly linked list.
Definition TList.h:38
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:708
void Add(TObject *obj) override
Definition TList.h:81
static TClass * Class()
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:149
Mother of all ROOT objects.
Definition TObject.h:42
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:462
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:227
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:549
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:507
The most important graphics class in the ROOT system.
Definition TPad.h:28
TList * GetListOfPrimitives() const override
Definition TPad.h:247
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot.
Definition TQObject.cxx:865
virtual Bool_t HasConnection(const char *signal_name) const
Return true if there is any object connected to this signal.
Definition TQObject.cxx:523
Bool_t Disconnect(const char *signal=nullptr, void *receiver=nullptr, const char *slot=nullptr)
Disconnects signal of this object from slot of receiver.
A specialized TSelector for TTree::Draw.
virtual Int_t GetDimension() const
Sequenceable collection abstract base class.
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition TString.cxx:545
const char * Data() const
Definition TString.h:384
TString & Append(const char *cs)
Definition TString.h:581
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2385
virtual Int_t Sizeof() const
Returns size string will occupy on I/O buffer.
Definition TString.cxx:1407
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
Tree Input Dialog Widget.
Definition TTreeInput.h:22
A TTree represents a columnar dataset.
Definition TTree.h:89
TVirtualTreePlayer * GetPlayer()
Load the TTreePlayer (if not already done).
Definition TTree.cxx:6416
void Draw(Option_t *opt) override
Default Draw method for all objects.
Definition TTree.h:478
static TClass * Class()
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual TCanvas * GetCanvas() const =0
STL class.
@ PAR_MIN
Definition CommonDefs.h:43
@ PAR_MAX
Definition CommonDefs.h:44
@ PAR_VAL
Definition CommonDefs.h:42
@ kFP_PRED1D
Definition CommonDefs.h:33
@ kFP_PQET
Definition CommonDefs.h:20
@ kFP_CLOSE
Definition CommonDefs.h:30
@ kFP_ADD
Definition CommonDefs.h:17
@ kFP_CHEB7
Definition CommonDefs.h:12
@ kFP_RESET
Definition CommonDefs.h:30
@ kFP_FILE
Definition CommonDefs.h:17
@ kFP_YMIN
Definition CommonDefs.h:21
@ kFP_UPDATE
Definition CommonDefs.h:30
@ kFP_MUSR
Definition CommonDefs.h:19
@ kFP_POL6
Definition CommonDefs.h:10
@ kFP_LGSL
Definition CommonDefs.h:23
@ kFP_XMIN
Definition CommonDefs.h:21
@ kFP_CHEB2
Definition CommonDefs.h:11
@ kFP_LMIN2
Definition CommonDefs.h:23
@ kFP_XYGAUS
Definition CommonDefs.h:13
@ kFP_CHEB6
Definition CommonDefs.h:12
@ kFP_MCHIS
Definition CommonDefs.h:19
@ kFP_MLINF
Definition CommonDefs.h:19
@ kFP_IMERR
Definition CommonDefs.h:18
@ kFP_POL1
Definition CommonDefs.h:9
@ kFP_POL5
Definition CommonDefs.h:9
@ kFP_LFUM
Definition CommonDefs.h:23
@ kFP_POL0
Definition CommonDefs.h:9
@ kFP_NOSEL
Definition CommonDefs.h:36
@ kFP_INTEG
Definition CommonDefs.h:18
@ kFP_DATAS
Definition CommonDefs.h:34
@ kFP_CHEB9
Definition CommonDefs.h:12
@ kFP_LAND
Definition CommonDefs.h:8
@ kFP_CHEB1
Definition CommonDefs.h:11
@ kFP_NONE
Definition CommonDefs.h:17
@ kFP_MLIST
Definition CommonDefs.h:19
@ kFP_CHEB0
Definition CommonDefs.h:11
@ kFP_POL4
Definition CommonDefs.h:9
@ kFP_CHEB4
Definition CommonDefs.h:11
@ kFP_EXPO
Definition CommonDefs.h:8
@ kFP_POL7
Definition CommonDefs.h:10
@ kFP_GSLSA
Definition CommonDefs.h:25
@ kFP_CHEB5
Definition CommonDefs.h:11
@ kFP_MITR
Definition CommonDefs.h:28
@ kFP_UFUNC
Definition CommonDefs.h:33
@ kFP_IFITR
Definition CommonDefs.h:18
@ kFP_BIGAUS
Definition CommonDefs.h:13
@ kFP_XYLANN
Definition CommonDefs.h:13
@ kFP_MINMETHOD
Definition CommonDefs.h:24
@ kFP_FLIST
Definition CommonDefs.h:8
@ kFP_TLIST
Definition CommonDefs.h:33
@ kFP_POL3
Definition CommonDefs.h:9
@ kFP_FIT
Definition CommonDefs.h:30
@ kFP_NORMADD
Definition CommonDefs.h:17
@ kFP_GAUSN
Definition CommonDefs.h:8
@ kFP_MTOL
Definition CommonDefs.h:28
@ kFP_CHEB8
Definition CommonDefs.h:12
@ kFP_CHEB3
Definition CommonDefs.h:11
@ kFP_FUMILI
Definition CommonDefs.h:24
@ kFP_RBUST
Definition CommonDefs.h:17
@ kFP_POL2
Definition CommonDefs.h:9
@ kFP_POL8
Definition CommonDefs.h:10
@ kFP_SIMPLX
Definition CommonDefs.h:23
@ kFP_PDEF
Definition CommonDefs.h:20
@ kFP_PRED2D
Definition CommonDefs.h:33
@ kFP_USERG
Definition CommonDefs.h:18
@ kFP_XYZGAUS
Definition CommonDefs.h:14
@ kFP_PARS
Definition CommonDefs.h:17
@ kFP_XYLAN
Definition CommonDefs.h:13
@ kFP_MBINL
Definition CommonDefs.h:19
@ kFP_ALTFUNC
Definition CommonDefs.h:37
@ kFP_DNOST
Definition CommonDefs.h:20
@ kFP_GSLLM
Definition CommonDefs.h:25
@ kFP_BFGS
Definition CommonDefs.h:25
@ kFP_MUBIN
Definition CommonDefs.h:19
@ kFP_CONV
Definition CommonDefs.h:17
@ kFP_GAUS
Definition CommonDefs.h:8
@ kFP_PVER
Definition CommonDefs.h:20
@ kFP_PRED3D
Definition CommonDefs.h:33
@ kFP_GALIB
Definition CommonDefs.h:26
@ kFP_LMIN
Definition CommonDefs.h:23
@ kFP_POL9
Definition CommonDefs.h:10
@ kFP_EMPW1
Definition CommonDefs.h:17
@ kFP_DNONE
Definition CommonDefs.h:20
@ kFP_GSLPR
Definition CommonDefs.h:25
@ kFP_USER
Definition CommonDefs.h:16
@ kFP_SCAN
Definition CommonDefs.h:26
@ kFP_LANDN
Definition CommonDefs.h:8
@ kFP_ALLW1
Definition CommonDefs.h:18
@ kFP_COMBINATION
Definition CommonDefs.h:24
@ kFP_XYEXP
Definition CommonDefs.h:13
@ kFP_GSLFR
Definition CommonDefs.h:25
@ kFP_BFGS2
Definition CommonDefs.h:25
@ kFP_ADDLS
Definition CommonDefs.h:18
@ kFP_DADVB
Definition CommonDefs.h:20
@ kFP_LGAS
Definition CommonDefs.h:23
@ kFP_MERR
Definition CommonDefs.h:28
@ kFP_PREVFIT
Definition CommonDefs.h:33
@ kFP_MIGRAD
Definition CommonDefs.h:23
@ kFP_TMVAGA
Definition CommonDefs.h:26
@ kFP_DSAME
Definition CommonDefs.h:20
std::multimap< TObject *, TF1 * >::iterator fPrevFitIter
Definition CommonDefs.h:4
leg AddEntry(h1,"Histogram filled with random numbers","f")
TGraphErrors * gr
Definition legend1.C:25
TH1F * h1
Definition legend1.C:5
TFitResultPtr FitObject(TH1 *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
fitting function for a TH1 (called from TH1::Fit)
Definition HFitImpl.cxx:977
void Init2DGaus(const ROOT::Fit::BinData &data, TF1 *f1)
compute initial parameter for 2D gaussian function given the fit data Set the sigma limits for zero t...
TFitResultPtr UnBinFit(ROOT::Fit::UnBinData *data, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption)
fit an unbin data set (from tree or from histogram buffer) using a TF1 pointer and fit options.
Definition HFitImpl.cxx:826
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.
void InitGaus(const ROOT::Fit::BinData &data, TF1 *f1)
compute initial parameter for gaussian function given the fit data Set the sigma limits for zero top ...
int Range
Definition Foption.h:39
int Nograph
Definition Foption.h:42
int Quiet
Definition Foption.h:29
int Like
Definition Foption.h:34
int W1
Definition Foption.h:36
int Gradient
Definition Foption.h:40
int Robust
Definition Foption.h:48
double hRobust
Definition Foption.h:51
int Plus
Definition Foption.h:43
int Integral
Definition Foption.h:44
int Bound
Definition Foption.h:31
int Nostore
Definition Foption.h:41
int More
Definition Foption.h:38
int Minuit
Definition Foption.h:46
int Errors
Definition Foption.h:37
int Verbose
Definition Foption.h:30
TLine l
Definition textangle.C:4