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
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 {
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) {
295 // case gaussian or Landau
296 } else if ( 110 == special || 410 == special ) {
300 }
301}
302
303////////////////////////////////////////////////////////////////////////////////
304/// Splits the entry in fDataSet to get the selected variables and cuts
305/// from the text.
306
308{
309 // Get the entry
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),
361 fChangedParams (kFALSE)
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
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);
385 fTab->Associate(this);
386
387 TGHorizontalFrame *cf1 = new TGHorizontalFrame(this, 350, 20, kFixedWidth);
388 cf1->SetCleanup(kDeepCleanup);
389 fUpdateButton = new TGTextButton(cf1, "&Update", kFP_UPDATE);
392 kLHintsExpandX, 0, 20, 2, 2));
393
394
395 fFitButton = new TGTextButton(cf1, "&Fit", kFP_FIT);
396 fFitButton->Associate(this);
397 cf1->AddFrame(fFitButton, new TGLayoutHints(kLHintsTop |
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);
419
422
423 gROOT->GetListOfCleanups()->Add(this);
424
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
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
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);
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);
543 TGLabel *label1 = new TGLabel(tf0,"Type:");
544 tf0 -> AddFrame(label1, new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0));
545
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
553 lb->Resize(lb->GetWidth(), 200);
554 tf0->AddFrame(fTypeFit, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
555 fTypeFit->Associate(this);
556
559 fFuncList->Resize(194, 20);
561
563 lb -> Resize(lb->GetWidth(), 500);
564 tf0 -> AddFrame(fFuncList, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
565 fFuncList->Associate(this);
566
568
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));
601
605 //fEnteredFunc->SetMaxLength(4000); // use default value (~4000)
608 assert(te);
609 fEnteredFunc->SetText(te->GetTitle());
610 fEnteredFunc->SetToolTipText("Enter file_name/function_name or a function expression");
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));
624 gf1->AddFrame(s1, new TGLayoutHints(kLHintsExpandX));
625
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);
638 fSetParam = new TGTextButton(tf5, "Set Parameters...", kFP_PARS);
639 tf5->AddFrame(fSetParam, new TGLayoutHints(kLHintsRight |
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));
673 gf->AddFrame(h1, new TGLayoutHints(kLHintsExpandX));
674
679 fMethodList->Resize(140, 20);
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
691 h2->AddFrame(v1, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
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");
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,
713 v1h->AddFrame(fRobustValue, new TGLayoutHints(kLHintsLeft));
714 v2->AddFrame(v1h, new TGLayoutHints(kLHintsNormal, 0, 0, 12, 2));
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));
734 gf->AddFrame(h3, new TGLayoutHints(kLHintsExpandX));
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);
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);
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);
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));
791 gf->AddFrame(h5, new TGLayoutHints(kLHintsExpandX));
792
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);
808 fNoStoreDrawing->SetToolTipText("'N'- do not store the function, do not draw it");
810
811 h6->AddFrame(v5, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
812
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
823 v6->AddFrame(v61, new TGLayoutHints(kLHintsRight | kLHintsTop,
824 0, 0, (4+fDrawSame->GetHeight())*2, 0));
825
827 gf->AddFrame(h6, new TGLayoutHints(kLHintsExpandX, 20, 0, 2, 0));
828
830 kLHintsExpandY, 5, 5, 0, 0));
831 // sliderX
835 kLHintsCenterY, 0, 5, 0, 0));
836
842
844 fSliderX->SetScale(5);
846
847
854
855 // sliderY
859 kLHintsCenterY, 0, 5, 0, 0));
860
866
868 fSliderY->SetScale(5);
870
877
878 // sliderZ
882 kLHintsCenterY, 0, 5, 0, 0));
884 fSliderZ->SetScale(5);
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));
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
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 {
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
947
948 MakeTitle(fMinimization, "Method");
949
952 fMinMethodList->Resize(290, 20);
954
956 lb->Resize(lb->GetWidth(), 500);
958
961
962 // Set the status to the default minimization options!
965 } else if ( ROOT::Math::MinimizerOptions::DefaultMinimizerType() == "Minuit" ) {
967 } else {
969 }
971
972 MakeTitle(fMinimization, "Settings");
973 TGLabel *hslabel1 = new TGLabel(fMinimization,"Use ENTER key to validate a new value or click");
975 TGLabel *hslabel2 = new TGLabel(fMinimization,"on Reset button to set the defaults.");
977
979
981 TGLabel *errlabel = new TGLabel(hsv1,"Error definition (default = 1): ");
983 1, 1, 5, 7));
984 TGLabel *tollabel = new TGLabel(hsv1,"Max tolerance (precision): ");
986 1, 1, 5, 7));
987 TGLabel *itrlabel = new TGLabel(hsv1,"Max number of iterations: ");
989 1, 1, 5, 5));
990 hs->AddFrame(hsv1, new TGLayoutHints(kLHintsNormal, 60, 0, 0, 0));
991
998 1, 1, 0, 3));
1005 1, 1, 3, 3));
1012 1, 1, 3, 3));
1013 hs->AddFrame(hsv2, new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
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));
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
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());
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 TQObject::Disconnect("TCanvas", "Closed()");
1260 delete fgFitDialog;
1261 fgFitDialog = 0;
1262}
1263
1264////////////////////////////////////////////////////////////////////////////////
1265/// Set the fit panel GUI according to the selected object.
1266
1268{
1269 if (!fFitObject) return;
1270
1271 DrawSelection(true);
1272
1273 if ( fType == kObjectTree )
1274 // Don't do anything with the sliders, as they work with TAxis
1275 // that are not defined for the TTree
1276 return;
1277
1278 // sliders
1279 if (fType != kObjectTree) { // This is as fDim > 0
1280 TH1* hist = 0;
1281 switch (fType) {
1282 case kObjectHisto:
1283 hist = (TH1*)fFitObject;
1284 break;
1285
1286 case kObjectGraph:
1287 hist = ((TGraph*)fFitObject)->GetHistogram();
1288 break;
1289
1290 case kObjectMultiGraph:
1291 hist = ((TMultiGraph*)fFitObject)->GetHistogram();
1292 break;
1293
1294 case kObjectGraph2D:
1295 hist = ((TGraph2D*)fFitObject)->GetHistogram("empty");
1296 break;
1297
1298 case kObjectHStack:
1299 hist = (TH1 *)((THStack *)fFitObject)->GetHists()->First();
1300
1301 case kObjectTree:
1302 default:
1303 break;
1304 }
1305
1306
1307 if (!hist) {
1308 Error("UpdateGUI","No hist is present - this should not happen, please report."
1309 "The FitPanel might be in an inconsistent state");
1310 //assert(hist);
1311 return;
1312 }
1313
1314 fSliderX->Disconnect("PositionChanged()");
1315 fSliderXMin->Disconnect("ValueChanged()");
1316 fSliderXMax->Disconnect("ValueChanged()");
1317
1318 if (!fSliderXParent->IsMapped())
1320
1321 fXaxis = hist->GetXaxis();
1322 fYaxis = hist->GetYaxis();
1323 fZaxis = hist->GetZaxis();
1327
1328 if (ixmin > 1 || ixmax < ixrange) {
1331 } else {
1334 }
1335
1336 fSliderX->SetScale(5);
1337
1339 fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ),
1340 fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
1343 fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ),
1344 fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
1346
1347 fSliderX->Connect("PositionChanged()","TFitEditor",this, "DoSliderXMoved()");
1348 fSliderXMax->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderXChanged()");
1349 fSliderXMin->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderXChanged()");
1350 }
1351
1352 if (fDim > 1) {
1353 fSliderY->Disconnect("PositionChanged()");
1354 fSliderYMin->Disconnect("ValueChanged()");
1355 fSliderYMax->Disconnect("ValueChanged()");
1356
1357 if (!fSliderYParent->IsMapped())
1359 if (fSliderZParent->IsMapped())
1361
1362 Int_t iymin = 0, iymax = 0, iyrange = 0;
1363 switch (fType) {
1364 case kObjectHisto:
1365 case kObjectGraph2D:
1366 case kObjectHStack:
1367 iyrange = fYaxis->GetNbins();
1368 iymin = fYaxis->GetFirst();
1369 iymax = fYaxis->GetLast();
1370 break;
1371
1372 case kObjectGraph:
1373 case kObjectMultiGraph:
1374 case kObjectTree:
1375 default:
1376 //not implemented
1377 break;
1378 }
1379
1380 if (iymin > 1 || iymax < iyrange) {
1383 } else {
1386 }
1387
1388 fSliderY->SetScale(5);
1389
1391 fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ),
1392 fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
1395 fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ),
1396 fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
1398
1399 fSliderY->Connect("PositionChanged()","TFitEditor",this, "DoSliderYMoved()");
1400 fSliderYMax->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderYChanged()");
1401 fSliderYMin->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderYChanged()");
1402 }
1403
1404
1405 if (fDim > 2) {
1406 fSliderZ->Disconnect("PositionChanged()");
1407
1408 if (!fSliderZParent->IsMapped())
1410
1411 Int_t izmin = 0, izmax = 0, izrange = 0;
1412 switch (fType) {
1413 case kObjectHStack:
1414 case kObjectHisto:
1415 izrange = fZaxis->GetNbins();
1416 izmin = fZaxis->GetFirst();
1417 izmax = fZaxis->GetLast();
1418 break;
1419
1420 case kObjectGraph:
1421 case kObjectGraph2D:
1422 case kObjectMultiGraph:
1423 case kObjectTree:
1424 default:
1425 //not implemented
1426 break;
1427 }
1428
1429 if (izmin > 1 || izmax < izrange) {
1432 } else {
1435 }
1436
1437 fSliderZ->SetScale(5);
1438 fSliderZ->Connect("PositionChanged()","TFitEditor",this, "DoSliderZMoved()");
1439 }
1440}
1441
1442////////////////////////////////////////////////////////////////////////////////
1443/// Slot called when the user clicks on an object inside a canvas.
1444/// Updates pointers to the parent pad and the selected object
1445/// for fitting (if suitable).
1446
1448{
1449 if (event != kButton1Down) return;
1450
1451 if ( !obj ) {
1452 DoNoSelection();
1453 return;
1454 }
1455
1456 // is obj suitable for fitting?
1457 if (!SetObjectType(obj)) return;
1458
1459 fParentPad = pad;
1460 fFitObject = obj;
1461 ShowObjectName(obj);
1462 UpdateGUI();
1463
1464 ConnectSlots();
1465
1467
1468 if (fitFunc)
1469 {
1470 //fFuncPars = FuncParams_t( fitFunc->GetNpar() );
1472
1473 TString tmpStr = fitFunc->GetExpFormula();
1474 TGLBEntry *en = 0;
1475 // If the function comes from a C raw function.
1476 if ( tmpStr.Length() == 0 )
1477 {
1478 // Show the name of the function
1479 fEnteredFunc->SetText(fitFunc->GetName());
1480 en= fFuncList->FindEntry(fitFunc->GetName());
1481 // Don't allow edition!
1483 }
1484 // otherwise, it's got a formula
1485 else
1486 {
1487 // Show the formula
1488 fEnteredFunc->SetText(fitFunc->GetExpFormula().Data());
1489 en= fFuncList->FindEntry(fitFunc->GetExpFormula().Data());
1491 }
1492 // Select the proper entry in the function list
1493 if (en) fFuncList->Select(en->EntryId());
1494 }
1495 else
1496 { // if there is no fit function in the object
1497 // Use the selected function in fFuncList
1499 // Add the text to fEnteredFunc
1500 if (te && fNone->GetState() == kButtonDown)
1501 fEnteredFunc->SetText(te->GetTitle());
1502 else if (te && fAdd->GetState() == kButtonDown)
1503 {
1505 tmpStr += '+';
1506 tmpStr += te->GetTitle();
1508 }
1509 else if (te && fNormAdd->GetState() == kButtonDown)
1510 {
1512 tmpStr += '+';
1513 tmpStr += te -> GetTitle();
1514 fEnteredFunc -> SetText(tmpStr);
1515 }
1516 else if (te && fConv->GetState() == kButtonDown)
1517 {
1519 tmpStr += '*';
1520 tmpStr +=te->GetTitle();
1522 }
1523 else if ( !te )
1524 // If there is no space, an error message is shown:
1525 // Error in <TString::AssertElement>: out of bounds: i = -1, Length = 0
1526 // If there is no function selected, then put nothing.
1527 fEnteredFunc->SetText(" ");
1528 }
1530
1531
1532 // Update the information about the selected object.
1539 DoLinearFit();
1540}
1541
1542////////////////////////////////////////////////////////////////////////////////
1543/// Slot called when users close a TCanvas or when the user select
1544/// no object.
1545
1547{
1548 if (gROOT->GetListOfCanvases()->IsEmpty()) {
1549 Terminate();
1550 return;
1551 }
1552
1553 // Minimize user interaction until an object is selected
1555 fParentPad = 0;
1556 fFitObject = 0;
1557 fStatusBar->SetText("No selection",0);
1559 Layout();
1560
1565}
1566
1567////////////////////////////////////////////////////////////////////////////////
1568/// When obj is deleted, clear fFitObject if fFitObject = obj.
1569
1571{
1572 if (obj == fFitObject) {
1573 fFitObject = 0;
1575 fStatusBar->SetText("No selection",0);
1577 Layout();
1578
1582
1583 TQObject::Connect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
1584 "TFitEditor",this,
1585 "SetFitObject(TVirtualPad *, TObject *, Int_t)");
1586 TQObject::Connect("TCanvas", "Closed()", "TFitEditor", this,
1587 "DoNoSelection()");
1588
1589 DoUpdate();
1590 return;
1591 }
1592 if (obj == fParentPad) {
1593 fFitObject = 0;
1594 fParentPad = 0;
1596 fStatusBar->SetText("No selection",0);
1598 Layout();
1599
1603 }
1604}
1605
1606////////////////////////////////////////////////////////////////////////////////
1607/// Fills the list of functions depending on the type of fit
1608/// selected.
1609
1611{
1613 // Case when the user has selected predefined functions in 1D.
1614 if ( fTypeFit->GetSelected() == kFP_PRED1D && fDim <= 1 ) {
1615 // Fill function list combo box.
1616 fFuncList->AddEntry("gaus" , kFP_GAUS);
1617 fFuncList->AddEntry("gausn", kFP_GAUSN);
1618 fFuncList->AddEntry("expo", kFP_EXPO);
1619 fFuncList->AddEntry("landau", kFP_LAND);
1620 fFuncList->AddEntry("landaun",kFP_LANDN);
1621 fFuncList->AddEntry("pol0", kFP_POL0);
1622 fFuncList->AddEntry("pol1", kFP_POL1);
1623 fFuncList->AddEntry("pol2", kFP_POL2);
1624 fFuncList->AddEntry("pol3", kFP_POL3);
1625 fFuncList->AddEntry("pol4", kFP_POL4);
1626 fFuncList->AddEntry("pol5", kFP_POL5);
1627 fFuncList->AddEntry("pol6", kFP_POL6);
1628 fFuncList->AddEntry("pol7", kFP_POL7);
1629 fFuncList->AddEntry("pol8", kFP_POL8);
1630 fFuncList->AddEntry("pol9", kFP_POL9);
1631 fFuncList->AddEntry("cheb0", kFP_CHEB0);
1632 fFuncList->AddEntry("cheb1", kFP_CHEB1);
1633 fFuncList->AddEntry("cheb2", kFP_CHEB2);
1634 fFuncList->AddEntry("cheb3", kFP_CHEB3);
1635 fFuncList->AddEntry("cheb4", kFP_CHEB4);
1636 fFuncList->AddEntry("cheb5", kFP_CHEB5);
1637 fFuncList->AddEntry("cheb6", kFP_CHEB6);
1638 fFuncList->AddEntry("cheb7", kFP_CHEB7);
1639 fFuncList->AddEntry("cheb8", kFP_CHEB8);
1640 fFuncList->AddEntry("cheb9", kFP_CHEB9);
1641 fFuncList->AddEntry("user", kFP_USER);
1642
1643 // Need to be setted this way, otherwise when the functions
1644 // are removed, the list doesn't show them.
1646 lb->Resize(lb->GetWidth(), 200);
1647
1648 // Select Gaus1D by default
1650
1651 }
1652 // Case for predefined 2D functions
1653 else if ( fTypeFit->GetSelected() == kFP_PRED2D && fDim == 2 ) {
1654 fFuncList->AddEntry("xygaus", kFP_XYGAUS);
1655 fFuncList->AddEntry("bigaus", kFP_BIGAUS);
1656 fFuncList->AddEntry("xyexpo", kFP_XYEXP);
1657 fFuncList->AddEntry("xylandau", kFP_XYLAN);
1658 fFuncList->AddEntry("xylandaun", kFP_XYLANN);
1659
1660 // Need to be setted this way, otherwise when the functions
1661 // are removed, the list doesn't show them.x
1663 lb->Resize(lb->GetWidth(), 200);
1664
1665 // Select Gaus2D by default
1667 }
1668 // Case for user defined functions. References to these functions
1669 // are kept by the fitpanel, so the information is gathered from
1670 // there.
1671 else if ( fTypeFit->GetSelected() == kFP_UFUNC ) {
1673
1674 // Add system functions
1675 for (auto f : fSystemFuncs) {
1676 // Don't include system functions that has been previously
1677 // used to fit, as those are included under the kFP_PREVFIT
1678 // section.
1679 if ( strncmp(f->GetName(), "PrevFit", 7) != 0 ) {
1680 // If the dimension of the object coincides with the
1681 // dimension of the function, then include the function in
1682 // the list. It will also include de function if the
1683 // dimension of the object is 0 (i.e. a multivariable
1684 // TTree) as it is currently imposible to know how many
1685 // dimensions a TF1 coming from a C raw function has.
1686 if ( f->GetNdim() == fDim || fDim == 0) {
1687 fFuncList->AddEntry(f->GetName(), newid++);
1688 }
1689 }
1690 }
1691
1692 // If no function was added
1693 if ( newid != kFP_ALTFUNC )
1695 else if( fDim == 1 ) {
1696 // Select predefined 1D functions for 1D objects
1698 } else if( fDim == 2 ) {
1699 // Select predefined 2D functions for 2D objects
1701 }
1702 }
1703 // Case for previously used functions.
1704 else if ( fTypeFit->GetSelected() == kFP_PREVFIT ) {
1706
1707 // Look only for those functions used in the selected object
1708 std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(fFitObject);
1709 // Then go over all those functions and add them to the list
1710 for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
1711 fFuncList->AddEntry(it->second->GetName(), newid++);
1712 }
1713
1714 // If no functions were added.
1715 if ( newid == kFP_ALTFUNC ) {
1716 // Remove the entry previous fit from fTypeFit
1718 if( fDim == 1 )
1719 // Select predefined 1D functions for 1D objects
1721 else if ( fDim == 2 )
1722 // Select predefined 2D functions for 2D objects
1724 else
1725 // For more than 2 dimensions, select the user functions.
1727 }
1728 else
1729 // If there is there are previously used functions, select
1730 // the last one inserted.
1732 }
1733}
1734
1735////////////////////////////////////////////////////////////////////////////////
1736/// Fills the list of methods depending on the minimization library
1737/// selected.
1738
1740{
1742
1743 if ( fLibMinuit->GetState() == kButtonDown )
1744 {
1745 fMinMethodList->AddEntry("MIGRAD" , kFP_MIGRAD);
1746 fMinMethodList->AddEntry("SIMPLEX" , kFP_SIMPLX);
1747 fMinMethodList->AddEntry("SCAN" , kFP_SCAN);
1748 fMinMethodList->AddEntry("Combination" , kFP_COMBINATION);
1750 fStatusBar->SetText("MIGRAD",2);
1751 } else if ( fLibFumili->GetState() == kButtonDown )
1752 {
1753 fMinMethodList->AddEntry("FUMILI" , kFP_FUMILI);
1755 fStatusBar->SetText("FUMILI",2);
1756 } else if ( fLibGSL->GetState() == kButtonDown )
1757 {
1758 fMinMethodList->AddEntry("Fletcher-Reeves conjugate gradient" , kFP_GSLFR);
1759 fMinMethodList->AddEntry("Polak-Ribiere conjugate gradient" , kFP_GSLPR);
1760 fMinMethodList->AddEntry("BFGS conjugate gradient" , kFP_BFGS);
1761 fMinMethodList->AddEntry("BFGS conjugate gradient (Version 2)", kFP_BFGS2);
1762 fMinMethodList->AddEntry("Levenberg-Marquardt" , kFP_GSLLM);
1763 fMinMethodList->AddEntry("Simulated Annealing" , kFP_GSLSA);
1765 fStatusBar->SetText("CONJFR",2);
1766 } else if ( fLibGenetics->GetState() == kButtonDown )
1767 {
1768 if ( gPluginMgr->FindHandler("ROOT::Math::Minimizer","GAlibMin") ) {
1769 fMinMethodList->AddEntry("GA Lib Genetic Algorithm" , kFP_GALIB);
1771 } else if (gPluginMgr->FindHandler("ROOT::Math::Minimizer","Genetic")) {
1772 fMinMethodList->AddEntry("TMVA Genetic Algorithm" , kFP_TMVAGA);
1774 }
1775 } else // if ( fLibMinuit2->GetState() == kButtonDown )
1776 {
1777 fMinMethodList->AddEntry("MIGRAD" , kFP_MIGRAD);
1778 fMinMethodList->AddEntry("SIMPLEX" , kFP_SIMPLX);
1779 fMinMethodList->AddEntry("FUMILI" , kFP_FUMILI);
1780 fMinMethodList->AddEntry("SCAN" , kFP_SCAN);
1781 fMinMethodList->AddEntry("Combination" , kFP_COMBINATION);
1783 fStatusBar->SetText("MIGRAD",2);
1784 }
1785}
1786
1787void SearchCanvases(TSeqCollection* canvases, std::vector<TObject*>& objects)
1788{
1789 // Auxiliary function to recursively search for objects inside the
1790 // current canvases.
1791
1793 // Iterate over all the canvases in canvases.
1794 while(TObject* obj = (TObject*) canvasIter()) {
1795 // If the object is another canvas, call this function
1796 // recursively.
1797 if ( TPad* can = dynamic_cast<TPad*>(obj))
1798 SearchCanvases(can->GetListOfPrimitives(), objects);
1799 // Otherwhise, if it's a recognised object, add it to the vector
1800 else if ( dynamic_cast<TH1*>(obj)
1801 || dynamic_cast<TGraph*>(obj)
1802 || dynamic_cast<TGraph2D*>(obj)
1803 || dynamic_cast<TMultiGraph*>(obj)
1804 || dynamic_cast<THStack*>(obj)
1805 || dynamic_cast<TTree*>(obj) ) {
1806 bool insertNew = true;
1807 // Be careful no to insert the same element twice.
1808 for ( std::vector<TObject*>::iterator i = objects.begin(); i != objects.end(); ++i )
1809 if ( (*i) == obj ) {
1810 insertNew = false;
1811 break;
1812 }
1813 // If the object is not already in the vector, then insert
1814 // it.
1815 if ( insertNew ) objects.push_back(obj);
1816 }
1817 }
1818}
1819
1820////////////////////////////////////////////////////////////////////////////////
1821/// Create a combo box with all the possible objects to be fitted.
1822
1824{
1825 // Get the title of the entry selected, so that we can select it
1826 // again once the fDataSet has been refilled.
1829 if ( entry ) {
1830 selEntryStr = entry->GetTitle();
1831 }
1832
1833 // Remove all the elements
1835 std::vector<TObject*> objects;
1836
1837 // Get all the objects registered in gDirectory
1838 if (gDirectory) {
1839 TList * l = gDirectory->GetList();
1840 if (l) {
1841 TIter next(l);
1842 TObject* obj = NULL;
1843 while ( (obj = (TObject*) next()) ) {
1844 // But only if they are of a type recognized by the FitPanel
1845 if ( dynamic_cast<TH1*>(obj) ||
1846 dynamic_cast<TGraph2D*>(obj) ||
1847 dynamic_cast<TTree*>(obj) ) {
1848 objects.push_back(obj);
1849 }
1850 }
1851 }
1852 }
1853
1854 // Look for all the drawn objects. The method will take care the
1855 // same objects are not inserted twice.
1856 SearchCanvases(gROOT->GetListOfCanvases(), objects);
1857
1858 // Add all the objects stored in the vector
1859 int selected = kFP_NOSEL;
1860 // Add the No selection.
1862 fDataSet->AddEntry("No Selection", newid++);
1863 for ( std::vector<TObject*>::iterator i = objects.begin(); i != objects.end(); ++i ) {
1864 // Insert the name as the class name followed by the name of the
1865 // object.
1866 TString name = (*i)->ClassName(); name.Append("::"); name.Append((*i)->GetName());
1867 // Check whether the names are the same!
1868 if ( selEntryStr && name == selEntryStr )
1869 selected = newid;
1871 }
1872
1873 // If there was an entry selected (which should be always the case
1874 // except the first time this method is executed), then make it the
1875 // selected one again.
1876 if (entry) {
1877 fDataSet->Select(selected);
1878 }
1879}
1880
1881////////////////////////////////////////////////////////////////////////////////
1882/// Create method list in a combo box.
1883
1885{
1886 TGComboBox *c = new TGComboBox(parent, id);
1887 c->AddEntry("Chi-square", kFP_MCHIS);
1888 c->AddEntry("Binned Likelihood", kFP_MBINL);
1889 c->AddEntry("Unbinned Likelihood", kFP_MUBIN);
1890 //c->AddEntry("User", kFP_MUSER); //for later use
1891 c->Select(kFP_MCHIS);
1892 return c;
1893}
1894
1895////////////////////////////////////////////////////////////////////////////////
1896/// Slot connected to advanced option button (opens a dialog).
1897
1902
1903////////////////////////////////////////////////////////////////////////////////
1904/// Slot connected to 'include emtry bins and forse all weights to 1' setting.
1905
1912
1913////////////////////////////////////////////////////////////////////////////////
1914
1916{
1917 if ( fUseRange->GetState() == kButtonDown ) {
1919 // Get the function
1920 TF1* tmpTF1 = FindFunction();
1921 if ( !tmpTF1 ) {
1924 tmpTF1 = (TF1*) GetFitObjectListOfFunctions()->FindObject( te->GetTitle() );
1925 }
1926 }
1927 // If the function has been retrieved, i.e. is a registered function.
1928 if ( tmpTF1 ) {
1929 Double_t xmin, ymin, zmin, xmax, ymax, zmax;
1930 // Get the range
1931 tmpTF1->GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
1932 // And set the sliders
1933 if ( fType != kObjectTree ) {
1937 if ( fDim > 1 ) {
1941 }
1942 }
1943 }
1944 }
1946 }
1947}
1948
1949////////////////////////////////////////////////////////////////////////////////
1950/// Slot connected to 'set all weights to 1' setting.
1951
1958
1959////////////////////////////////////////////////////////////////////////////////
1960/// Close the fit panel.
1961
1963{
1964 Hide();
1965}
1966
1967////////////////////////////////////////////////////////////////////////////////
1968/// Easy here!
1969
1975
1976////////////////////////////////////////////////////////////////////////////////
1977/// Perform a fit with current parameters' settings.
1978
1980{
1981 if (!fFitObject) return;
1982 //if (!fParentPad) return;
1983
1984 // If fNone->GetState() == kButtonDisabled means the function is
1985 // not editable, i.e. it comes from a raw C function. So in this
1986 // case, it is editable and we have to check wheather the formula
1987 // is well built.
1989 {
1990 // If not, then show an error message and leave.
1992 "Error...", "2) Verify the entered function string!",
1993 kMBIconStop,kMBOk, 0);
1994 return;
1995 }
1996
1997 // Set the button so that the user cannot use it while fitting, set
1998 // the mouse to watch type and so on.
2000 if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kWatch);
2001 gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
2002
2003 TVirtualPad *save = nullptr;
2004 if ( fParentPad ) {
2005 fParentPad->Disconnect("RangeAxisChanged()");
2006 save = gPad;
2007 gPad = fParentPad;
2008 fParentPad->cd();
2009
2010 if (fParentPad->GetCanvas())
2011 fParentPad->GetCanvas()->SetCursor(kWatch);
2012 }
2013
2014 // Get the ranges from the sliders
2017
2018 // Create a static pointer to fitFunc. Every second call to the
2019 // DoFit method, the old fitFunc is deleted. We need not to delete
2020 // the function after the fitting in case we want to do Advaced
2021 // graphics. The VirtualFitter need the function to be alived. One
2022 // problem, after the last fit the function is never deleted, but
2023 // ROOT's garbage collector will do the job for us.
2024 static TF1 *fitFunc = nullptr;
2025 if ( fitFunc ) {
2026 //std::cout << "TFitEditor::DoFit - deleting fit function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2027 delete fitFunc;
2028 }
2030
2031 std::cout << "TFitEditor::DoFit - using function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2032 // This assert
2033 if (!fitFunc) {
2034 Error("DoFit","This should have never happend, the fitfunc pointer is NULL! - Please Report" );
2035 return;
2036 }
2037
2038 // set parameters from panel in function
2040 // Get the options stored in the GUI elements.
2045
2046 // Call the fit method, depending on the object to fit.
2047 switch (fType) {
2048 case kObjectHisto: {
2049
2050 TH1 *hist = dynamic_cast<TH1*>(fFitObject);
2051 if (hist)
2053
2054 break;
2055 }
2056 case kObjectGraph: {
2057
2058 TGraph *gr = dynamic_cast<TGraph*>(fFitObject);
2059 if (gr)
2060 FitObject(gr, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2061 break;
2062 }
2063 case kObjectMultiGraph: {
2064
2065 TMultiGraph *mg = dynamic_cast<TMultiGraph*>(fFitObject);
2066 if (mg)
2067 FitObject(mg, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2068
2069 break;
2070 }
2071 case kObjectGraph2D: {
2072
2073 TGraph2D *g2d = dynamic_cast<TGraph2D*>(fFitObject);
2074 if (g2d)
2075 FitObject(g2d, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2076
2077 break;
2078 }
2079 case kObjectHStack: {
2080 // N/A
2081 break;
2082 }
2083 case kObjectTree: {
2084 // The three is a much more special case. The steps for
2085 // fitting have to be done manually here until they are
2086 // properly implemented within a FitObject method in
2087 // THFitImpl.cxx
2088
2089 // Retrieve the variables and cuts selected from the current
2090 // tree.
2091 TString variables;
2092 TString cuts;
2093 GetTreeVarsAndCuts(fDataSet, variables, cuts);
2094
2095 // This should be straight forward and the return should
2096 // never be called.
2097 TTree *tree = dynamic_cast<TTree*>(fFitObject);
2098 if ( !tree ) return;
2099
2100 // These method calls are just to set up everything for the
2101 // fitting. It's taken from another script.
2102 gROOT->ls();
2103 tree->Draw(variables,cuts,"goff");
2104
2105 auto player = tree->GetPlayer();
2106 if ( !player ) {
2107 Error("DoFit","Player reference is NULL");
2108 return;
2109 }
2110
2111 auto selector = dynamic_cast<TSelectorDraw *>(player->GetSelector());
2112 if ( !selector ) {
2113 Error("DoFit","Selector reference is NULL");
2114 return;
2115 }
2116
2117 // use pointer stored in the tree (not copy the data in)
2118 unsigned int ndim = player->GetDimension();
2119 if ( ndim == 0 ) {
2120 Error("DoFit","NDIM == 0");
2121 return;
2122 }
2123
2124 std::vector<double *> vlist;
2125 for (unsigned int i = 0; i < ndim; ++i) {
2126 double * v = selector->GetVal(i);
2127 if (v != 0) vlist.push_back(v);
2128 else
2129 std::cerr << "pointer for variable " << i << " is zero" << std::endl;
2130 }
2131 if (vlist.size() != ndim) {
2132 Error("DoFit","Vector is not complete");
2133 return;
2134 }
2135
2136 // fill the data
2137 Long64_t nrows = player->GetSelectedRows();
2138 if ( !nrows ) {
2139 Error("DoFit","NROWS == 0");
2140 return;
2141 }
2142
2144
2145 for ( int i = 0; i < std::min(int(fitdata->Size()),10); ++i) {
2146 // print j coordinate
2147 for (unsigned int j = 0; j < ndim; ++j) {
2148 printf(" x_%d [%d] = %f \n", j, i,*(fitdata->Coords(i)+j) );
2149 }
2150 printf("\n");
2151 }
2152
2153
2154 //TVirtualFitter::SetDefaultFitter("Minuit");
2157 fitOption.Verbose=1;
2158
2159 // After all the set up is performed, then do the Fit!!
2161
2162 break;
2163 }
2164 }
2165
2166 // if SAME is set re-plot the function
2167 // useful in case histogram was drawn with HIST
2168 // and no function will be drawm)
2170 fitFunc->Draw("same");
2171
2172
2173 // update parameters value shown in dialog
2174 //if (!fFuncPars) fFuncPars = new Double_t[fitFunc->GetNpar()][3];
2176
2177 // Save fit data for future use as a PrevFit function.
2179 TString name = TString::Format("PrevFit-%d", (int) fPrevFit.size() + 1);
2180 if (!strstr(fitFunc->GetName(),"PrevFit"))
2181 name.Append(TString::Format("-%s", fitFunc->GetName()));
2182 tmpTF1->SetName(name.Data());
2183 fPrevFit.emplace(fFitObject, tmpTF1);
2184 fSystemFuncs.emplace_back( copyTF1(tmpTF1) );
2185
2186 float xmin = 0.f, xmax = 0.f, ymin = 0.f, ymax = 0.f, zmin = 0.f, zmax = 0.f;
2187 if ( fParentPad ) {
2189 // As the range is not changed, save the old values and restore
2190 // after the GUI has been updated. It would be more elegant to
2191 // disconnect the signal from fParentPad, however, this doesn't
2192 // work for unknown reasons.
2194 if ( fDim > 1 ) fSliderY->GetPosition(ymin, ymax);
2195 if ( fDim > 2 ) fSliderZ->GetPosition(zmin, zmax);
2196 fParentPad->Update();
2197 }
2198
2199 // In case the fit method draws something! Set the canvas!
2200 fParentPad = gPad;
2201 UpdateGUI();
2202
2203 // Change the sliders if necessary.
2204 if ( fParentPad ) {
2206 if ( fType != kObjectTree && fDim > 1 ) { fSliderY->SetPosition(ymin, ymax); DoSliderYMoved(); }
2207 if ( fType != kObjectTree && fDim > 2 ) { fSliderZ->SetPosition(zmin, zmax); DoSliderZMoved(); }
2208 if (fParentPad->GetCanvas())
2209 fParentPad->GetCanvas()->SetCursor(kPointer);
2210 fParentPad->Connect("RangeAxisChanged()", "TFitEditor", this, "UpdateGUI()");
2211
2212 if (save) gPad = save;
2216 }
2217
2218 // Restore the Fit button and mouse cursor to their proper state.
2219 if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kPointer);
2220 gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
2222
2223 if ( !fTypeFit->FindEntry("Prev. Fit") )
2225
2227}
2228
2229////////////////////////////////////////////////////////////////////////////////
2230/// Check entered function string.
2231
2233{
2234 Int_t rvalue = 0;
2235 if ( fDim == 1 || fDim == 0 ) {
2236 TF1 form("tmpCheck", fname);
2237 // coverity[uninit_use_in_call]
2238 rvalue = form.IsValid() ? 0 : -1;
2239 } else if ( fDim == 2 ) {
2240 TF2 form("tmpCheck", fname);
2241 // coverity[uninit_use_in_call]
2242 rvalue = form.IsValid() ? 0 : -1;
2243 } else if ( fDim == 3 ) {
2244 TF3 form("tmpCheck", fname);
2245 // coverity[uninit_use_in_call]
2246 rvalue = form.IsValid() ? 0 : -1;
2247 }
2248
2249 return rvalue;
2250}
2251
2252////////////////////////////////////////////////////////////////////////////////
2253/// Slot connected to addition of predefined functions. It will
2254/// insert the next selected function with a plus sign so that it
2255/// doesn't override the current content of the formula.
2256
2258{
2259 static Bool_t first = kFALSE;
2261 if (on) {
2262 if (!first) {
2263 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
2264 s += "(0)";
2266 first = kTRUE;
2268 }
2269 } else {
2270 first = kFALSE;
2271 }
2272}
2273////////////////////////////////////////////////////////////////////////////////
2274/// Slot connected to addition of predefined functions. It will
2275/// insert the next selected function with a plus sign so that it
2276/// doesn't override the current content of the formula.
2277
2279{
2280 /*
2281 static Bool_t first = kFALSE;
2282 TString s = fEnteredFunc->GetText();
2283 if (on) {
2284 if (!first) {
2285 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
2286 fEnteredFunc->SetText(s.Data());
2287 first = kTRUE;
2288 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2289 }
2290 } else {
2291 first = kFALSE;
2292 }*/
2293
2294 if (on) Info("DoNormAddition","Normalized addition is selected");
2295}
2296
2297////////////////////////////////////////////////////////////////////////////////
2298/// Slot connected to addition of predefined functions. It will
2299/// insert the next selected function with a plus sign so that it
2300/// doesn't override the current content of the formula.
2301
2303{
2304 /*
2305 static Bool_t first = kFALSE;
2306 TString s = fEnteredFunc->GetText();
2307 if (on) {
2308 if (!first) {
2309 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
2310 // s += "(0)";
2311 fEnteredFunc->SetText(s.Data());
2312 first = kTRUE;
2313 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2314 }
2315 } else
2316 first = kFALSE;*/
2317
2318 if (on) Info("DoConvolution","Convolution is selected");
2319}
2320
2321////////////////////////////////////////////////////////////////////////////////
2322/// Selects the data set to be fitted
2323
2325{
2326 if ( selected == kFP_NOSEL ) {
2327 DoNoSelection();
2328 return;
2329 }
2330
2331 // Get the name and class of the selected object.
2332 TGTextLBEntry* textEntry = static_cast<TGTextLBEntry*>(fDataSet->GetListBox()->GetEntry(selected));
2333 if (!textEntry) return;
2334 TString textEntryStr = textEntry->GetText()->GetString();
2335 TString name = textEntry->GetText()->GetString()+textEntry->GetText()->First(':')+2;
2336 TString className = textEntryStr(0,textEntry->GetText()->First(':'));
2337
2338 // Check the object exists in the ROOT session and it is registered
2339 TObject* objSelected(0);
2340 if ( className == "TTree" ) {
2341 // It's a tree, so the name is before the space (' ')
2343 if ( name.First(' ') == kNPOS )
2344 lookStr = name;
2345 else
2346 lookStr = name(0, name.First(' '));
2347 //std::cout << "\t1 SITREE: '" << lookStr << "'" << std::endl;
2348 objSelected = gROOT->FindObject(lookStr);
2349 } else {
2350 // It's not a tree, so the name is the complete string
2351 //std::cout << "\t1 NOTREE: '" << name << "'" << std::endl;
2352 objSelected = gROOT->FindObject(name);
2353 }
2354 if ( !objSelected )
2355 {
2356 //std::cerr << "Object not found! Please report the error! " << std::endl;
2357 return;
2358 }
2359
2360 // If it is a tree, and there are no variables selected, show a dialog
2361 if ( objSelected->InheritsFrom(TTree::Class()) &&
2362 name.First(' ') == kNPOS ) {
2363 char variables[256] = {0}; char cuts[256] = {0};
2364 strlcpy(variables, "Sin input!", 256);
2365 new TTreeInput( fClient->GetRoot(), GetMainFrame(), variables, cuts );
2366 if ( strcmp ( variables, "" ) == 0 ) {
2367 DoNoSelection();
2368 return;
2369 }
2370 ProcessTreeInput(objSelected, selected, variables, cuts);
2371 }
2372
2373 // Search the canvas where the object is drawn, if any
2374 TPad* currentPad = NULL;
2375 bool found = false;
2376 std::queue<TPad*> stPad;
2377 TIter padIter( gROOT->GetListOfCanvases() );
2378 while ( TObject* canvas = static_cast<TObject*>(padIter() ) ) {
2379 if ( dynamic_cast<TPad*>(canvas) )
2380 stPad.push(dynamic_cast<TPad*>(canvas));
2381 }
2382
2383 while ( !stPad.empty() && !found ) {
2384 currentPad = stPad.front();
2385 stPad.pop();
2386 TIter elemIter( currentPad->GetListOfPrimitives() );
2387 while ( TObject* elem = static_cast<TObject*>(elemIter() ) ) {
2388 if ( elem == objSelected ) {
2389 found = true;
2390 break;
2391 } else if ( dynamic_cast<TPad*>(elem) )
2392 stPad.push( dynamic_cast<TPad*>(elem) );
2393 }
2394 }
2395
2396 // Set the proper object and canvas (if found!)
2397 SetFitObject( found ? currentPad : nullptr, objSelected, kButton1Down);
2398}
2399
2401{
2402 // If the input is valid, insert the tree with the selections as an entry to fDataSet
2403 TString entryName = (objSelected)->ClassName(); entryName.Append("::"); entryName.Append((objSelected)->GetName());
2404 entryName.Append(" (\""); entryName.Append(variables); entryName.Append("\", \"");
2405 entryName.Append(cuts); entryName.Append("\")");
2407 fDataSet->InsertEntry(entryName, newid, selected );
2409}
2410
2411////////////////////////////////////////////////////////////////////////////////
2412/// Slot connected to predefined fit function settings.
2413
2415{
2417
2418 // check that selected passesd value is the correct one in the TextEntry
2419 R__ASSERT( selected == te->EntryId());
2420 //std::cout << "calling do function " << selected << " " << te->GetTitle() << " function " << te->EntryId() << std::endl;
2421 //selected = te->EntryId();
2422
2423 bool editable = false;
2425 {
2426 // Get the function selected and check weather it is a raw C
2427 // function or not
2428 TF1* tmpTF1 = FindFunction();
2429 if ( !tmpTF1 )
2430 {
2432 tmpTF1 = (TF1*) GetFitObjectListOfFunctions()->FindObject( te->GetTitle() );
2433 }
2434 if ( tmpTF1 && strcmp(tmpTF1->GetExpFormula(), "") )
2435 {
2436 editable = kTRUE;
2437 fEnteredFunc->SetText(tmpTF1->GetExpFormula());
2438 }
2439 else
2440 {
2441 if ( selected <= kFP_USER )
2442 editable = kTRUE;
2443 else
2444 editable = kFALSE;
2445 fEnteredFunc->SetText(te->GetTitle());
2446 }
2447 // Once you have the function, set the editable.
2449 }
2450 else if (fAdd -> GetState() == kButtonDown)
2451 {
2452 // If the add button is down don't replace the fEnteredFunc text
2453 Int_t np = 0;
2454 TString s = "";
2455 if (!strcmp(fEnteredFunc->GetText(), ""))
2456 {
2457 fEnteredFunc->SetText(te->GetTitle());
2458 }
2459 else
2460 {
2461 s = fEnteredFunc->GetTitle();
2462 TFormula tmp("tmp", fEnteredFunc->GetText());
2463 np = tmp.GetNpar();
2464 }
2465 if (np)
2466 s += TString::Format("+%s(%d)", te->GetTitle(), np);
2467 else
2468 s += TString::Format("%s(%d)", te->GetTitle(), np);
2470 editable = true;
2471 }
2472 else if (fNormAdd->GetState() == kButtonDown)
2473 {
2474 // If the normadd button is down don't replace the fEnteredFunc text
2475 Int_t np = 0;
2476 TString s = "";
2477 if (!strcmp(fEnteredFunc->GetText(), ""))
2478 {
2479 fEnteredFunc->SetText(te->GetTitle());
2480 }
2481 else
2482 {
2483 s = fEnteredFunc->GetTitle();
2484 TFormula tmp("tmp", fEnteredFunc->GetText());
2485 np = tmp.GetNpar();
2486 }
2487 if (np)
2488 s += TString::Format("+%s", te->GetTitle());
2489 else
2490 s += TString::Format("%s", te->GetTitle());
2492 //std::cout <<fEnteredFunc->GetText()<<std::endl;
2493 editable = true;
2494 }
2495 else if (fConv->GetState() == kButtonDown)
2496 {
2497 // If the conv button is down don't replace the fEnteredFunc text
2498 Int_t np = 0;
2499 TString s = "";
2500 if (!strcmp(fEnteredFunc->GetText(), ""))
2501 fEnteredFunc->SetText(te->GetTitle());
2502 else
2503 {
2504 s = fEnteredFunc->GetTitle();
2505 TFormula tmp("tmp", fEnteredFunc->GetText());
2506 np = tmp.GetNpar();
2507 }
2508 if (np)
2509 s += TString::Format("*%s", te->GetTitle());
2510 else
2511 s += TString::Format("%s", te->GetTitle());
2513 //std::cout <<fEnteredFunc->GetText()<<std::endl;
2514 editable = true;
2515 }
2516
2517
2518 // Get the final name in fEnteredFunc to process the function that
2519 // it would create
2521
2522 // create TF1 with the passed string. Delete previous one if existing
2523 if (tmpStr.Contains("pol") || tmpStr.Contains("++")) {
2525 } else {
2527 }
2528
2530 fSelLabel->SetText(tmpStr.Sizeof()>30?tmpStr(0,30)+"...":tmpStr);
2532
2533 // reset function parameters if the number of parameters of the new
2534 // function is different from the old one!
2536 //std::cout << "TFitEditor::DoFunction - using function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2537
2538 if ( fitFunc && (unsigned int) fitFunc->GetNpar() != fFuncPars.size() ) {
2540 fFuncPars.resize(fitFunc->GetNpar());
2541 else
2542 fFuncPars.clear();
2543 }
2544 if ( fitFunc ) {
2545 //std::cout << "TFitEditor::DoFunction - deleting function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2546 delete fitFunc;
2547 }
2548}
2549
2550////////////////////////////////////////////////////////////////////////////////
2551/// Slot connected to entered function in text entry.
2552
2554{
2555 if (!strcmp(fEnteredFunc->GetText(), "")) return;
2556
2557 // Check if the function is well built
2559
2560 if (ok != 0) {
2562 "Error...", "3) Verify the entered function string!",
2563 kMBIconStop,kMBOk, 0);
2564 return;
2565 }
2566
2567 // And set the label with the entered text if everything is fine.
2569 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
2571}
2572
2573////////////////////////////////////////////////////////////////////////////////
2574/// Slot connected to linear fit settings.
2575
2577{
2578 if (fLinearFit->GetState() == kButtonDown) {
2579 //fSetParam->SetState(kButtonDisabled);
2583 //fNoChi2->SetState(kButtonUp);
2584 } else {
2585 //fSetParam->SetState(kButtonUp);
2590 //fNoChi2->SetState(kButtonDisabled);
2591 }
2592}
2593
2594////////////////////////////////////////////////////////////////////////////////
2595/// Slot connected to 'no chi2' option settings.
2596
2598{
2599 //LM: no need to do operations here
2600 // if (fLinearFit->GetState() == kButtonUp)
2601 // fLinearFit->SetState(kButtonDown, kTRUE);
2602}
2603////////////////////////////////////////////////////////////////////////////////
2604/// Slot connected to 'robust fitting' option settings.
2605
2613
2614////////////////////////////////////////////////////////////////////////////////
2615/// Slot connected to 'no storing, no drawing' settings.
2616
2622
2623////////////////////////////////////////////////////////////////////////////////
2624/// Slot connected to print option settings.
2625
2627{
2628 // Change the states of the buttons depending of which one is
2629 // selected.
2631 Int_t id = btn->WidgetId();
2632 switch (id) {
2633 case kFP_PDEF:
2634 if (on) {
2638 }
2639 fStatusBar->SetText("Prn: DEF",4);
2640 break;
2641 case kFP_PVER:
2642 if (on) {
2646 }
2647 fStatusBar->SetText("Prn: VER",4);
2648 break;
2649 case kFP_PQET:
2650 if (on) {
2654 }
2655 fStatusBar->SetText("Prn: QT",4);
2656 default:
2657 break;
2658 }
2659}
2660
2661////////////////////////////////////////////////////////////////////////////////
2662/// Reset all fit parameters.
2663
2665{
2666 if ( fParentPad ) {
2668 fParentPad->Update();
2669 }
2670 fEnteredFunc->SetText("gaus");
2671
2672 // To restore temporary points and sliders
2673 UpdateGUI();
2674
2679 if (fUseRange->GetState() == kButtonDown)
2693 // if (fNoChi2->GetState() == kButtonDown)
2694 // fNoChi2->SetState(kButtonUp, kFALSE);
2695 if (fDrawSame->GetState() == kButtonDown)
2702 fFuncList->Select(1, kTRUE);
2703
2704 // minimization tab
2713 }
2717 }
2721 }
2722}
2723
2724////////////////////////////////////////////////////////////////////////////////
2725/// Open set parameters dialog.
2726
2728{
2729 // Get the function.
2731 //std::cout << "TFitEditor::DoSetParameters - using function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2732
2733 if (!fitFunc) { Error("DoSetParameters","NUll function"); return; }
2734
2735 // case of special functions (gaus, expo, etc...) if the function
2736 // has not defined the parameters yet. For those, don't let the
2737 // parameters to be all equal to 0, as we can provide some good
2738 // starting value.
2739 if (fFuncPars.size() == 0) {
2740 switch (fType) {
2741 case kObjectHisto:
2743 break;
2744 case kObjectGraph:
2746 break;
2747 case kObjectMultiGraph:
2749 break;
2750 case kObjectGraph2D:
2752 break;
2753 case kObjectHStack:
2754 case kObjectTree:
2755 default:
2756 break;
2757 }
2758 // The put these parameters into the fFuncPars structure
2760 }
2761 else {
2762 // Otherwise, put the parameters in the function
2764 }
2765
2766 if ( fParentPad ) fParentPad->Disconnect("RangeAxisChanged()");
2767 Int_t ret = 0;
2768 /// fit parameter dialog willbe deleted automatically when closed
2769 new TFitParametersDialog(gClient->GetDefaultRoot(), GetMainFrame(),
2771
2772 // Once the parameters are set in the fitfunction, save them.
2774
2775 // check return code to see if parameters settings have been modified
2776 // in this case we need to set the B option when fitting
2777 if (ret) fChangedParams = kTRUE;
2778
2779
2780 if ( fParentPad ) fParentPad->Connect("RangeAxisChanged()", "TFitEditor", this, "UpdateGUI()");
2781
2782 if ( fNone->GetState() != kButtonDisabled ) {
2783 //std::cout << "TFitEditor::DoSetParameters - deleting function " << fitFunc->GetName() << " " << fitFunc << std::endl;
2784 delete fitFunc;
2785 }
2786}
2787
2788////////////////////////////////////////////////////////////////////////////////
2789/// Slot connected to range settings on x-axis.
2790
2792{
2793 if ( !fFitObject ) return;
2794
2797
2799
2800 DrawSelection();
2801}
2802
2803////////////////////////////////////////////////////////////////////////////////
2804/// Draws the square around the object showing where the limits for
2805/// fitting are.
2806
2808{
2809#ifndef R__HAS_COCOA
2810 static Int_t px1old, py1old, px2old, py2old; // to remember the square drawn.
2811#endif
2812
2813 if ( !fParentPad ) return;
2814
2815 if (restore) {
2816#ifndef R__HAS_COCOA
2821#endif
2822 return;
2823 }
2824
2825 Int_t px1,py1,px2,py2;
2826
2827 TVirtualPad *save = 0;
2828 save = gPad;
2829 gPad = fParentPad;
2830 gPad->cd();
2831
2832 Double_t xleft = 0;
2833 Double_t xright = 0;
2836
2837 Float_t ymin, ymax;
2838 if ( fDim > 1 )
2839 {
2840 ymin = fYaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5));//gPad->GetUymin();
2841 ymax = fYaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5));//gPad->GetUymax();
2842 }
2843 else
2844 {
2845 ymin = gPad->GetUymin();
2846 ymax = gPad->GetUymax();
2847 }
2848
2849 px1 = gPad->XtoAbsPixel(xleft);
2850 py1 = gPad->YtoAbsPixel(ymin);
2851 px2 = gPad->XtoAbsPixel(xright);
2852 py2 = gPad->YtoAbsPixel(ymax);
2853
2854 if (gPad->GetCanvas()) gPad->GetCanvas()->FeedbackMode(kTRUE);
2855 gPad->SetLineWidth(1);
2856 gPad->SetLineColor(2);
2857#ifndef R__HAS_COCOA
2858 // With Cocoa XOR is fake, so no need in erasing the old box, it's
2859 // done by clearing the backing store and repainting inside a special
2860 // window.
2862
2863 px1old = px1;
2864 py1old = py1;
2865 px2old = px2;
2866 py2old = py2;
2867#endif // R__HAS_COCOA
2868 gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
2869
2870 if(save) gPad = save;
2871}
2872
2873////////////////////////////////////////////////////////////////////////////////
2874/// Sincronize the numeric sliders with the graphical one.
2875
2877{
2879 float xmin, xmax;
2881 fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( xmin ) ) );
2882 fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( xmax ) ) );
2883 return;
2884 }
2885
2888
2890
2891 DrawSelection();
2892}
2893
2894////////////////////////////////////////////////////////////////////////////////
2895/// Slot connected to range settings on y-axis.
2896
2898{
2899 if ( !fFitObject ) return;
2900
2903
2905
2906 DrawSelection();
2907}
2908
2909////////////////////////////////////////////////////////////////////////////////
2910///syncronize the numeric slider with the graphical one.
2911
2913{
2915 float ymin, ymax;
2917 fSliderYMin->SetNumber( fYaxis->GetBinLowEdge( static_cast<Int_t>( ymin ) ) );
2918 fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( ymax ) ) );
2919 return;
2920 }
2921
2924
2926
2927 DrawSelection();
2928}
2929
2930////////////////////////////////////////////////////////////////////////////////
2931/// Slot connected to range settings on z-axis.
2932
2936
2937////////////////////////////////////////////////////////////////////////////////
2938/// Open a dialog for getting a user defined method.
2939
2941{
2943 "Info", "Dialog of user method is not implemented yet",
2945}
2946
2947////////////////////////////////////////////////////////////////////////////////
2948/// Set the function to be used in performed fit.
2949
2950void TFitEditor::SetFunction(const char *function)
2951{
2952 fEnteredFunc->SetText(function);
2953}
2954
2955////////////////////////////////////////////////////////////////////////////////
2956/// Check whether the object suitable for fitting and set
2957/// its type, dimension and method combo box accordingly.
2958
2960{
2961 Bool_t set = kFALSE;
2962
2963 // For each kind of object, set a different status in the fit
2964 // panel.
2965 if (obj->InheritsFrom(TGraph::Class())) {
2967 set = kTRUE;
2968 fDim = 1;
2970 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
2973 fRobustValue->GetNumberEntry()->SetToolTipText("Set robust value");
2974 } else if (obj->InheritsFrom(TGraph2D::Class())) {
2976 set = kTRUE;
2977 fDim = 2;
2979 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
2981 } else if (obj->InheritsFrom(THStack::Class())) {
2983 set = kTRUE;
2984 TH1 *hist = (TH1 *)((THStack *)obj)->GetHists()->First();
2985 fDim = hist->GetDimension();
2987 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
2989 } else if (obj->InheritsFrom(TTree::Class())) {
2991 set = kTRUE;
2992 TString variables, cuts;
2993 GetTreeVarsAndCuts(fDataSet, variables, cuts);
2994 fDim = 1;
2995 for ( int i = 0; i < variables.Length() && fDim <= 2; ++i )
2996 if ( ':' == variables[i] ) fDim += 1;
2997 // For any three of dimension bigger than 2, set the dimension
2998 // to 0, as we cannot infer the dimension from the TF1s, it's
2999 // better to have 0 as reference.
3000 if ( fDim > 2 ) fDim = 0;
3002 fMethodList->AddEntry("Unbinned Likelihood", kFP_MUBIN);
3004 } else if (obj->InheritsFrom(TH1::Class())){
3006 set = kTRUE;
3007 fDim = ((TH1*)obj)->GetDimension();
3009 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
3010 fMethodList->AddEntry("Binned Likelihood", kFP_MBINL);
3012 } else if (obj->InheritsFrom(TMultiGraph::Class())) {
3014 set = kTRUE;
3015 fDim = 1;
3017 fMethodList->AddEntry("Chi-square", kFP_MCHIS);
3020 fRobustValue->GetNumberEntry()->SetToolTipText("Set robust value");
3021 }
3022
3023 // Depending on the dimension of the object, allow the
3024 // visualization of sliders.
3025 if ( fDim < 2 || fType == kObjectTree )
3027 else
3029
3030 if ( fDim < 1 || fType == kObjectTree )
3032 else
3034
3035 // And also, depending on the dimension, add predefined functions.
3036 if ( fDim == 1 ) {
3037 if ( !fTypeFit->FindEntry("Predef-1D") )
3039 } else {
3040 if ( fTypeFit->FindEntry("Predef-1D") )
3042 }
3043
3044 if ( fDim == 2 ) {
3045 if ( !fTypeFit->FindEntry("Predef-2D") )
3047 } else {
3048 if ( fTypeFit->FindEntry("Predef-2D") )
3050 }
3051
3052 return set;
3053}
3054
3055////////////////////////////////////////////////////////////////////////////////
3056/// Show object name on the top.
3057
3059{
3060 TString name;
3061 bool isTree = false;
3062
3063 // Build the string to be compared to look for the object.
3064 if (obj) {
3065 name = obj->ClassName();
3066 name.Append("::");
3067 name.Append(obj->GetName());
3068 isTree = strcmp(obj->ClassName(), "TTree") == 0;
3069 } else {
3070 name = "No object selected";
3071 }
3072 fStatusBar->SetText(name.Data(),0);
3073
3074 // If the selection was done in the fDataSet combo box, there is no need
3075 // to search through the list
3077 if ( selectedEntry ) {
3078 TString selectedName = selectedEntry->GetText()->GetString();
3079 if ( isTree )
3080 selectedName = selectedName(0, selectedName.First(' '));
3081 if ( name.CompareTo(selectedName) == 0 ) {
3082 Layout();
3083 return;
3084 }
3085 }
3086
3087 // Search through the list for the object
3089 bool found = false;
3090 while ( TGTextLBEntry* entry = static_cast<TGTextLBEntry*>
3091 ( fDataSet->GetListBox()->GetEntry(entryId)) ) {
3092 TString compareName = entry->GetText()->GetString();
3093 if ( isTree )
3094 compareName = compareName(0, compareName.First(' '));
3095 if ( name.CompareTo(compareName) == 0 ) {
3096 // If the object is found, select it
3097 fDataSet->Select(entryId, false);
3098 found = true;
3099 break;
3100 }
3101 entryId += 1;
3102 }
3103
3104 // If the object was not found, add it and select it.
3105 if ( !found ) {
3106 fDataSet->AddEntry(name.Data(), entryId);
3108 }
3109
3110 Layout();
3111}
3112
3113////////////////////////////////////////////////////////////////////////////////
3114/// Get draw options of the selected object.
3115
3117{
3118 if (!fParentPad) return "";
3119
3121 TObject *obj;
3122 while ((obj = next())) {
3123 if (obj == fFitObject) return next.GetOption();
3124 }
3125 return "";
3126}
3127
3128////////////////////////////////////////////////////////////////////////////////
3129/// Set selected minimization library in use.
3130
3132{
3134 Int_t id = bt->WidgetId();
3135
3136 switch (id) {
3137
3138 // Depending on the selected library, set the state of the rest
3139 // of the buttons.
3140 case kFP_LMIN:
3141 {
3142 if (on) {
3146 if ( fLibGSL->GetState() != kButtonDisabled )
3150 fStatusBar->SetText("LIB Minuit", 1);
3151 }
3152
3153 }
3154 break;
3155
3156 case kFP_LMIN2:
3157 {
3158 if (on) {
3162 if ( fLibGSL->GetState() != kButtonDisabled )
3166 fStatusBar->SetText("LIB Minuit2", 1);
3167 }
3168 }
3169 break;
3170
3171 case kFP_LFUM:
3172 {
3173 if (on) {
3177 if ( fLibGSL->GetState() != kButtonDisabled )
3181 fStatusBar->SetText("LIB Fumili", 1);
3182 }
3183 }
3184 break;
3185 case kFP_LGSL:
3186 {
3187 if (on) {
3191 if ( fLibGSL->GetState() != kButtonDisabled )
3195 fStatusBar->SetText("LIB GSL", 1);
3196 }
3197 }
3198 break;
3199 case kFP_LGAS:
3200 {
3201 if (on) {
3205 if ( fLibGSL->GetState() != kButtonDisabled )
3209 fStatusBar->SetText("LIB Genetics", 1);
3210 }
3211 }
3212 default:
3213 break;
3214 }
3216}
3217
3218////////////////////////////////////////////////////////////////////////////////
3219/// Set selected minimization method in use.
3220
3222{
3224 fStatusBar->SetText("MIGRAD",2);
3225 else if ( fMinMethodList->GetSelected() == kFP_FUMILI)
3226 fStatusBar->SetText("FUMILI",2);
3227 else if ( fMinMethodList->GetSelected() == kFP_SIMPLX )
3228 fStatusBar->SetText("SIMPLEX",2);
3229 else if ( fMinMethodList->GetSelected() == kFP_SCAN )
3230 fStatusBar->SetText("SCAN",2);
3232 fStatusBar->SetText("Combination",2);
3233 else if ( fMinMethodList->GetSelected() == kFP_GSLFR )
3234 fStatusBar->SetText("CONJFR",2);
3235 else if ( fMinMethodList->GetSelected() == kFP_GSLPR )
3236 fStatusBar->SetText("CONJPR",2);
3237 else if ( fMinMethodList->GetSelected() == kFP_BFGS )
3238 fStatusBar->SetText("BFGS",2);
3239 else if ( fMinMethodList->GetSelected() == kFP_BFGS2 )
3240 fStatusBar->SetText("BFGS2",2);
3241 else if ( fMinMethodList->GetSelected() == kFP_GSLLM )
3242 fStatusBar->SetText("GSLLM",2);
3243 else if ( fMinMethodList->GetSelected() == kFP_GSLSA)
3244 fStatusBar->SetText("SimAn",2);
3245 else if ( fMinMethodList->GetSelected() == kFP_TMVAGA )
3246 fStatusBar->SetText("TMVAGA",2);
3247 else if ( fMinMethodList->GetSelected() == kFP_GALIB )
3248 fStatusBar->SetText("GALIB",2);
3249
3250
3251}
3252
3253////////////////////////////////////////////////////////////////////////////////
3254/// Set the maximum number of iterations.
3255
3257{
3259 fStatusBar->SetText(Form("Itr: %ld",itr),2);
3260}
3261
3262////////////////////////////////////////////////////////////////////////////////
3263/// Create section title in the GUI.
3264
3265void TFitEditor::MakeTitle(TGCompositeFrame *parent, const char *title)
3266{
3267 TGCompositeFrame *ht = new TGCompositeFrame(parent, 350, 10,
3269 ht->AddFrame(new TGLabel(ht, title),
3270 new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
3271 ht->AddFrame(new TGHorizontal3DLine(ht),
3272 new TGLayoutHints(kLHintsExpandX | kLHintsCenterY, 5, 5, 2, 2));
3273 parent->AddFrame(ht, new TGLayoutHints(kLHintsTop, 5, 0, 5, 0));
3274}
3275
3276////////////////////////////////////////////////////////////////////////////////
3277/// Look in the list of function for TF1. If a TF1 is
3278/// found in the list of functions, it will be returned
3279
3281{
3282 // Get the list of functions of the fit object
3284 TF1* func = 0;
3285
3286 // If it exists
3287 if ( lf ) {
3288 // Add the posibility to select previous fit function
3289 if ( !fTypeFit->FindEntry("Prev. Fit") )
3291
3292 // Then add all these functions to the fPrefFit structure.
3293 TObject *obj2;
3294 TIter next(lf, kIterForward);
3295 // Go over all the elements in lf
3296 while ((obj2 = next())) {
3297 if (obj2->InheritsFrom(TF1::Class())) {
3298 func = (TF1 *)obj2;
3299 fPrevFitIter it;
3300 // No go over all elements in fPrevFit
3301 for ( it = fPrevFit.begin(); it != fPrevFit.end(); ++it) {
3302 // To see wheather the object corresponds with fFitObject
3303 if ( it->first != fFitObject ) continue;
3304 // And if so, whether the function is already included
3305 if ( strcmp( func->GetName(), it->second->GetName() ) == 0 )
3306 break;
3307 if ( strcmp( func->GetName(), "PrevFitTMP" ) == 0 )
3308 break;
3309 }
3310 // Only if the function is not already in fPrevFit, the
3311 // breaks in the loops would make it to be different to
3312 // fPrevFit.end() if the function is already stored
3313 if ( it == fPrevFit.end() ) {
3314 fPrevFit.emplace(fFitObject, copyTF1(func));
3315 }
3316 }
3317 }
3318
3319 // Select the PrevFit set
3321 // And fill the function list
3324
3325
3326 } else {
3327 // If there is no prev fit functions.
3329 // Call FillFunctionList as it might happen that the user is
3330 // changing from a TTree to another one, and thus the fFuncList
3331 // if not properly filled
3333 }
3334
3336
3337 return func;
3338}
3339
3340////////////////////////////////////////////////////////////////////////////////
3341/// Retrieve the fitting options from all the widgets.
3342
3344{
3345 drawOpts = "";
3346
3347 fitOpts.Range = (fUseRange->GetState() == kButtonDown);
3348 fitOpts.Integral = (fIntegral->GetState() == kButtonDown);
3350 fitOpts.Errors = (fBestErrors->GetState() == kButtonDown);
3352
3354 fitOpts.W1 = 2;
3355 else if (fAllWeights1->GetState() == kButtonDown)
3356 fitOpts.W1 = 1;
3357
3359 if ( !(fLinearFit->GetState() == kButtonDown) &&
3360 (tmpStr.Contains("pol") || tmpStr.Contains("++")) )
3361 fitOpts.Minuit = 1;
3362
3363 // if ( (int) fFuncPars.size() == npar )
3364 // for ( Int_t i = 0; i < npar; ++i )
3365 // if ( fFuncPars[i][PAR_MIN] != fFuncPars[i][PAR_MAX] )
3366 //
3367
3368 // //fitOpts.Bound = 1;
3369 // break;
3370 // }
3371
3372 if (fChangedParams) {
3373 //std::cout << "Params have changed setting the Bound option " << std::endl;
3374 fitOpts.Bound = 1;
3375 fChangedParams = kFALSE; // reset
3376 }
3377
3378 //fitOpts.Nochisq = (fNoChi2->GetState() == kButtonDown);
3379 fitOpts.Nostore = (fNoStoreDrawing->GetState() == kButtonDown);
3380 fitOpts.Nograph = (fNoDrawing->GetState() == kButtonDown);
3382 fitOpts.Gradient = (fUseGradient->GetState() == kButtonDown);
3383 fitOpts.Quiet = ( fOptQuiet->GetState() == kButtonDown );
3384 fitOpts.Verbose = ( fOptVerbose->GetState() == kButtonDown );
3385
3386 if ( !(fType != kObjectGraph) && (fEnableRobust->GetState() == kButtonDown) )
3387 {
3388 fitOpts.Robust = 1;
3389 fitOpts.hRobust = fRobustValue->GetNumber();
3390 }
3391
3393
3394 if ( fLibMinuit->GetState() == kButtonDown )
3395 minOpts.SetMinimizerType ( "Minuit");
3396 else if ( fLibMinuit2->GetState() == kButtonDown)
3397 minOpts.SetMinimizerType ( "Minuit2" );
3398 else if ( fLibFumili->GetState() == kButtonDown )
3399 minOpts.SetMinimizerType ("Fumili" );
3400 else if ( fLibGSL->GetState() == kButtonDown )
3401 minOpts.SetMinimizerType ("GSLMultiMin" );
3402
3404 minOpts.SetMinimizerAlgorithm( "Migrad" );
3405 else if ( fMinMethodList->GetSelected() == kFP_FUMILI)
3406 if ( fLibMinuit2->GetState() == kButtonDown )
3407 minOpts.SetMinimizerAlgorithm( "Fumili2" );
3408 else
3409 minOpts.SetMinimizerAlgorithm( "Fumili" );
3410 else if ( fMinMethodList->GetSelected() == kFP_SIMPLX )
3411 minOpts.SetMinimizerAlgorithm( "Simplex" );
3412 else if ( fMinMethodList->GetSelected() == kFP_SCAN )
3413 minOpts.SetMinimizerAlgorithm( "Scan" );
3415 minOpts.SetMinimizerAlgorithm( "Minimize" );
3416 else if ( fMinMethodList->GetSelected() == kFP_GSLFR )
3417 minOpts.SetMinimizerAlgorithm( "conjugatefr" );
3418 else if ( fMinMethodList->GetSelected() == kFP_GSLPR )
3419 minOpts.SetMinimizerAlgorithm( "conjugatepr" );
3420 else if ( fMinMethodList->GetSelected() == kFP_BFGS )
3421 minOpts.SetMinimizerAlgorithm( "bfgs" );
3422 else if ( fMinMethodList->GetSelected() == kFP_BFGS2 )
3423 minOpts.SetMinimizerAlgorithm( "bfgs2" );
3424 else if ( fMinMethodList->GetSelected() == kFP_GSLLM ) {
3425 minOpts.SetMinimizerType ("GSLMultiFit" );
3426 minOpts.SetMinimizerAlgorithm( "" );
3427 } else if ( fMinMethodList->GetSelected() == kFP_GSLSA) {
3428 minOpts.SetMinimizerType ("GSLSimAn" );
3429 minOpts.SetMinimizerAlgorithm( "" );
3430 } else if ( fMinMethodList->GetSelected() == kFP_TMVAGA) {
3431 minOpts.SetMinimizerType ("Geneti2c" );
3432 minOpts.SetMinimizerAlgorithm( "" );
3433 } else if ( fMinMethodList->GetSelected() == kFP_GALIB) {
3434 minOpts.SetMinimizerType ("GAlibMin" );
3435 minOpts.SetMinimizerAlgorithm( "" );
3436 }
3437
3438 minOpts.SetErrorDef ( fErrorScale->GetNumber() );
3439 minOpts.SetTolerance( fTolerance->GetNumber() );
3440 minOpts.SetMaxIterations(fIterations->GetIntNumber());
3441 minOpts.SetMaxFunctionCalls(fIterations->GetIntNumber());
3442}
3443
3445{
3446 // Set the state of some input widgets depending on whether the fit
3447 // function can be defined by text or if it is an existing one.
3448 if ( state )
3449 {
3450 fEnteredFunc-> SetState(kTRUE);
3451 fAdd -> SetState(kButtonUp, kFALSE);
3452 fNormAdd -> SetState(kButtonUp, kFALSE);
3453 fConv -> SetState(kButtonUp, kFALSE);
3454 fNone -> SetState(kButtonDown,kFALSE); // fNone::State is the one used as reference
3455 }
3456 else
3457 {
3458 fEnteredFunc-> SetState(kFALSE);
3459 fAdd -> SetState(kButtonDisabled, kFALSE);
3460 fNormAdd -> SetState(kButtonDisabled, kFALSE);
3461 fConv -> SetState(kButtonDisabled, kFALSE);
3462 fNone -> SetState(kButtonDisabled, kFALSE);
3463 }
3464}
3465
3467{
3468 // Return the ranges selected by the sliders.
3469
3470 // It's not working for trees as they don't have TAxis.
3471 if ( fType == kObjectTree ) return;
3472
3473 if ( fType != kObjectTree ) {
3478 drange.AddRange(0,xmin, xmax);
3479 }
3480
3481 if ( fDim > 1 ) {
3482 assert(fYaxis);
3487 drange.AddRange(1,ymin, ymax);
3488 }
3489 if ( fDim > 2 ) {
3490 assert(fZaxis);
3495 drange.AddRange(2,zmin, zmax);
3496 }
3497}
3498
3500{
3501 // Get the list of functions previously used in the fitobject.
3502
3504 if ( fFitObject ) {
3505 switch (fType) {
3506
3507 case kObjectHisto:
3508 listOfFunctions = ((TH1 *)fFitObject)->GetListOfFunctions();
3509 break;
3510
3511 case kObjectGraph:
3512 listOfFunctions = ((TGraph *)fFitObject)->GetListOfFunctions();
3513 break;
3514
3515 case kObjectMultiGraph:
3516 listOfFunctions = ((TMultiGraph *)fFitObject)->GetListOfFunctions();
3517 break;
3518
3519 case kObjectGraph2D:
3520 listOfFunctions = ((TGraph2D *)fFitObject)->GetListOfFunctions();
3521 break;
3522
3523 case kObjectHStack:
3524 case kObjectTree:
3525 default:
3526 break;
3527 }
3528 }
3529 return listOfFunctions;
3530}
3531
3533{
3534 // Looks for all the functions registered in the current ROOT
3535 // session.
3536
3537 // First, clean the copies stored in fSystemFunc
3538 for (auto func : fSystemFuncs)
3539 delete func;
3540
3541 fSystemFuncs.clear();
3542
3543 // Be carefull not to store functions that will be in the
3544 // predefined section
3545 const unsigned int nfuncs = 16;
3546 const char* fnames[nfuncs] = { "gaus" , "gausn", "expo", "landau",
3547 "landaun", "pol0", "pol1", "pol2",
3548 "pol3", "pol4", "pol5", "pol6",
3549 "pol7", "pol8", "pol9", "user"
3550 };
3551
3552 // No go through all the objects registered in gROOT
3553 TIter functionsIter(gROOT->GetListOfFunctions());
3554 TObject* obj;
3555 while( ( obj = (TObject*) functionsIter() ) ) {
3556 // And if they are TF1s
3557 if ( TF1* func = dynamic_cast<TF1*>(obj) ) {
3558 bool addFunction = true;
3559 // And they are not already registered in fSystemFunc
3560 for ( unsigned int i = 0; i < nfuncs; ++i ) {
3561 if ( strcmp( func->GetName(), fnames[i] ) == 0 ) {
3562 addFunction = false;
3563 break;
3564 }
3565 }
3566 // Add them.
3567 if ( addFunction )
3568 fSystemFuncs.emplace_back( copyTF1(func) );
3569 }
3570 }
3571}
3572
3574{
3575 // This function returns a TList with all the functions used in the
3576 // FitPanel to fit a given object. If the object passed is NULL,
3577 // then the object used is the currently selected one. It is
3578 // important to notice that the FitPanel is still the owner of
3579 // those functions. This means that the user SHOULD NOT delete any
3580 // of these functions, as the FitPanel will do so in the
3581 // destructor.
3582
3583 if (!obj) obj = fFitObject;
3584
3585 TList *retList = new TList();
3586
3587 std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(obj);
3588 for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
3589 retList->Add(it->second);
3590 }
3591
3592 return retList;
3593}
3594
3596{
3597 // Get the fit function selected or declared in the fiteditor
3598
3599 TF1 *fitFunc = 0;
3600 // If the function is not editable ==> it means it is registered in
3601 // gROOT
3602 if ( fNone->GetState() == kButtonDisabled )
3603 {
3604 // So we find it
3605 TF1* tmpF1 = FindFunction();
3606 // And if we don't find it, then it means there is something wrong!
3607 if ( tmpF1 == 0 )
3608 {
3610 "Error...", "1) Verify the entered function string!",
3611 kMBIconStop,kMBOk, 0);
3612 return 0;
3613 }
3614
3615 // Now we make a copy that will be used temporary. The caller of
3616 // the function should delete the returned function.
3617 fitFunc = (TF1*)tmpF1->IsA()->New();
3618 tmpF1->Copy(*fitFunc);
3619 // Copy the parameters of the function, if and only if the
3620 // parameters stored does not correspond with the ones of these
3621 // functions. Perhaps the user has already called
3622 // DoSetParameters. There is no way to know whether the
3623 // parameters have been modified, so we check the size of
3624 // fFuncPars against number of parameters.
3625 if ( int(fFuncPars.size()) != tmpF1->GetNpar() )
3626 {
3627 fitFunc->SetParameters(tmpF1->GetParameters());
3629 } else {
3631 }
3632 }
3633
3634 // If, we have no function at this point, it means that is is
3635 // described in fEnteredFunc, so we create it from scratch.
3636 if ( fitFunc == 0 )
3637 {
3640 double xmin, xmax, ymin, ymax, zmin, zmax;
3641 drange.GetRange(xmin, xmax, ymin, ymax, zmin, zmax);
3642
3643 // Depending of course on the number of dimensions the object
3644 // has. These commands will raise an error message if the user
3645 // has not defined the function properly
3646 if ( fDim == 1 || fDim == 0 )
3647 {
3648
3649 fitFunc = new TF1("PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax );
3650 //std::cout << "GetFitFunction - created function PrevFitTMP " << fEnteredFunc->GetText() << " " << fitFunc << std::endl;
3651 if (fNormAdd->IsOn())
3652 {
3653 if (fSumFunc) delete fSumFunc;
3655 fitFunc = new TF1("PrevFitTMP", *fSumFunc, xmin, xmax, fSumFunc->GetNpar());
3656 for (int i = 0; i < fitFunc->GetNpar(); ++i) fitFunc->SetParName(i, fSumFunc->GetParName(i) );
3657 //std::cout << "create fit normalized function " << fSumFunc << " fitfunc " << fitFunc << std::endl;
3658 }
3659
3660 if (fConv -> IsOn())
3661 {
3662 if (fConvFunc) delete fConvFunc;
3664 fitFunc = new TF1("PrevFitTMP", *fConvFunc, xmin, xmax, fConvFunc->GetNpar());
3665 for (int i = 0; i < fitFunc->GetNpar(); ++i) fitFunc->SetParName(i, fConvFunc->GetParName(i) );
3666 //std::cout << "create fit convolution function " << fSumFunc << " fitfunc " << fitFunc << std::endl;
3667 }
3668 }
3669 else if ( fDim == 2 ) {
3670 fitFunc = new TF2("PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax, ymin, ymax );
3671 }
3672 else if ( fDim == 3 ) {
3673 fitFunc = new TF3("PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax, ymin, ymax, zmin, zmax );
3674 }
3675
3676 // if the function is not a C defined
3677 if ( fNone->GetState() != kButtonDisabled )
3678 {
3679 // and the formulas are the same
3680 TF1* tmpF1 = FindFunction();
3681// if (tmpF1)
3682 //std::cout << "GetFitFunction: found existing function " << tmpF1 << " " << tmpF1->GetName() << " " << tmpF1->GetExpFormula() << std::endl;
3683// else
3684 //std::cout << "GetFitFunction: - no existing function found " << std::endl;
3685 if ( tmpF1 != 0 && fitFunc != 0 &&
3686 strcmp(tmpF1->GetExpFormula(), fEnteredFunc->GetText()) == 0 ) {
3687 // copy everything from the founction available in gROOT
3688 //std::cout << "GetFitFunction: copying tmp function in PrevFitTMP " << tmpF1->GetName() << " "
3689 // << tmpF1->GetExpFormula() << std::endl;
3690 tmpF1->Copy(*fitFunc);
3691 if ( int(fFuncPars.size()) != tmpF1->GetNpar() )
3692 {
3694 }
3695 }
3696 }
3697 }
3698
3699 return fitFunc;
3700}
@ kButton1Down
Definition Buttons.h:17
@ kWatch
Definition GuiTypes.h:375
@ kPointer
Definition GuiTypes.h:375
@ kVerticalFrame
Definition GuiTypes.h:381
@ kFixedWidth
Definition GuiTypes.h:387
@ kFitWidth
Definition GuiTypes.h:386
@ kHorizontalFrame
Definition GuiTypes.h:382
@ kFixedSize
Definition GuiTypes.h:390
ULong_t Pixel_t
Pixel value.
Definition GuiTypes.h:40
#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
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
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
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#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
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void SetMWMHints
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void SetWMPosition
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t SetWMSizeHints
char name[80]
Definition TGX11.cxx:110
float xmin
float ymin
float xmax
float ymax
R__EXTERN TPluginManager * gPluginMgr
R__EXTERN void * gTQSender
Definition TQObject.h:46
#define gROOT
Definition TROOT.h:411
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
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
Class describing the un-binned data sets (just x coordinates values) of any dimensions.
Definition UnBinData.h:46
static const std::string & DefaultMinimizerType()
const_iterator begin() const
const_iterator end() const
Allows to create advanced graphics from the last fit made in the fitpanel.
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:292
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:521
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:472
Int_t GetNbins() const
Definition TAxis.h:127
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:531
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:461
The Canvas class.
Definition TCanvas.h:23
Class wrapping convolution of two functions.
Int_t GetNpar() const
const char * GetParName(Int_t ipar) const
Class adding two functions: c1*f1+c2*f2.
Definition TF1NormSum.h:19
const char * GetParName(Int_t ipar) const
Definition TF1NormSum.h:66
Int_t GetNpar() const
Return the number of (non constant) parameters including the coefficients: for 2 functions: c1,...
1-Dim function class
Definition TF1.h:182
virtual Int_t GetNumber() const
Definition TF1.h:478
virtual void GetParLimits(Int_t ipar, Double_t &parmin, Double_t &parmax) const
Return limits for parameter ipar.
Definition TF1.cxx:1967
static TClass * Class()
virtual Int_t GetNpar() const
Definition TF1.h:461
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set lower and upper limits for parameter ipar.
Definition TF1.cxx:3538
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:623
virtual Double_t GetParameter(Int_t ipar) const
Definition TF1.h:492
A 2-Dim function with parameters.
Definition TF2.h:29
A 3-Dim function with parameters.
Definition TF3.h:28
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
A button abstract base class.
Definition TGButton.h:68
virtual void SetToolTipText(const char *text, Long_t delayms=400)
Set tool tip text associated with this button.
Definition TGButton.cxx:439
virtual EButtonState GetState() const
Definition TGButton.h:112
virtual void SetEnabled(Bool_t e=kTRUE)
Set enabled or disabled state of button.
Definition TGButton.cxx:453
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
Set button state.
Definition TGButton.cxx:229
Selects different options.
Definition TGButton.h:264
void SetState(EButtonState state, Bool_t emit=kFALSE) override
Set check button state.
const TGWindow * GetRoot() const
Returns current root (i.e.
Definition TGClient.cxx:223
UInt_t GetDisplayWidth() const
Get display width.
Definition TGClient.cxx:261
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
void RemoveAll() override
Remove all entries from combo box.
virtual TGLBEntry * GetSelectedEntry() const
Definition TGComboBox.h:115
virtual void AddEntry(TGString *s, Int_t id)
Definition TGComboBox.h:86
virtual void RemoveEntry(Int_t id=-1)
Remove entry. If id == -1, the currently selected entry is removed.
virtual TGListBox * GetListBox() const
Definition TGComboBox.h:110
virtual void Select(Int_t id, Bool_t emit=kTRUE)
Make the selected item visible in the combo box window and emit signals according to the second param...
virtual void InsertEntry(TGString *s, Int_t id, Int_t afterID)
Definition TGComboBox.h:92
virtual TGLBEntry * FindEntry(const char *s) const
Find entry by name.
virtual Int_t GetNumberOfEntries() const
Definition TGComboBox.h:107
The base class for composite widgets (menu bars, list boxes, etc.).
Definition TGFrame.h:289
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
virtual void ShowFrame(TGFrame *f)
Show sub frame.
Definition TGFrame.cxx:1196
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
virtual void HideFrame(TGFrame *f)
Hide sub frame.
Definition TGFrame.cxx:1182
Dragging the slider will generate the event:
virtual Float_t GetMaxPosition() const
virtual void GetPosition(Float_t &min, Float_t &max) const
virtual Float_t GetMinPosition() const
virtual void SetRange(Float_t min, Float_t max)
virtual void SetScale(Int_t scale)
virtual void SetPosition(Float_t min, Float_t max)
A subclasses of TGWindow, and is used as base class for some simple widgets (buttons,...
Definition TGFrame.h:80
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
virtual UInt_t GetDefaultHeight() const
Definition TGFrame.h:193
void MapWindow() override
map window
Definition TGFrame.h:206
virtual UInt_t GetOptions() const
Definition TGFrame.h:199
void UnmapWindow() override
unmap window
Definition TGFrame.h:208
UInt_t GetHeight() const
Definition TGFrame.h:227
A composite frame with a border and a title.
Definition TGFrame.h:524
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
This class handles GUI labels.
Definition TGLabel.h:24
virtual void SetTextColor(Pixel_t color, Bool_t global=kFALSE)
Changes text color.
Definition TGLabel.cxx:361
virtual void SetText(TGString *newText)
Set new text in label.
Definition TGLabel.cxx:179
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
Defines top level windows that interact with the system Window Manager.
Definition TGFrame.h:399
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 SetWindowName(const char *name=nullptr) override
Set window name. This is typically done via the window manager.
Definition TGFrame.cxx:1780
virtual Long_t GetIntNumber() const
Get the numeric value (integer representation).
virtual void SetNumber(Double_t val, Bool_t emit=kTRUE)
Set the numeric value (floating point representation).
virtual Double_t GetNumber() const
Get the numeric value (floating point representation).
void ReturnPressed() override
Return was pressed.
virtual void SetIntNumber(Long_t val, Bool_t emit=kTRUE)
Set the numeric value (integer representation).
TGNumberEntry is a number entry input widget with up/down buttons.
TGNumberEntryField * GetNumberEntry() const
Get the number entry field.
virtual void SetLimits(ELimit limits=TGNumberFormat::kNELNoLimits, Double_t min=0, Double_t max=1)
virtual void SetState(Bool_t enable=kTRUE)
Set the active state.
virtual Double_t GetNumber() const
virtual void SetNumber(Double_t val, Bool_t emit=kTRUE)
@ 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
void SetState(EButtonState state, Bool_t emit=kFALSE) override
Set radio button state.
Bool_t IsOn() const override
Definition TGButton.h:369
Provides a StatusBar widget.
Definition TGStatusBar.h:21
virtual void SetText(TGString *text, Int_t partidx=0)
Set text in partition partidx in status bar.
virtual void SetParts(Int_t npart)
Divide the status bar in npart equal sized parts.
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
virtual TGCompositeFrame * AddTab(TGString *text)
Add a tab to the tab widget.
Definition TGTab.cxx:373
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
const char * GetTitle() const override
Returns title of object.
const char * GetText() const
virtual void SelectAll()
Selects all text (i.e.
virtual void SetAlignment(ETextJustification mode=kTextLeft)
Sets the alignment of the text entry.
virtual void SetToolTipText(const char *text, Long_t delayms=500)
Set tool tip text associated with this text entry.
virtual void SetText(const char *text, Bool_t emit=kTRUE)
Sets text entry to text, clears the selection and moves the cursor to the end of the line.
Text string listbox entries.
Definition TGListBox.h:48
A composite frame that layout their children in vertical way.
Definition TGFrame.h:376
virtual void Associate(const TGWindow *w)
Definition TGWidget.h:72
virtual const TGWindow * GetMainFrame() const
Returns top level main frame.
Definition TGWindow.cxx:150
const TGWindow * GetParent() const
Definition TGWindow.h:83
virtual Bool_t IsMapped()
Returns kTRUE if window is mapped on screen, kFALSE otherwise.
Definition TGWindow.cxx:293
Graphics object made of three arrays X, Y and Z with the same number of points each.
Definition TGraph2D.h:41
static TClass * Class()
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
static TClass * Class()
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
TAxis * GetZaxis()
Definition TH1.h:574
static TClass * Class()
virtual Int_t GetDimension() const
Definition TH1.h:528
TAxis * GetXaxis()
Definition TH1.h:572
TAxis * GetYaxis()
Definition TH1.h:573
The Histogram stack class.
Definition THStack.h:40
static TClass * Class()
Iterator of linked list.
Definition TList.h:191
Option_t * GetOption() const override
Returns the object option stored in the list.
Definition TList.cxx:1141
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:575
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition TMultiGraph.h:34
static TClass * Class()
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
void ls(Option_t *option="") const override
List TNamed name and title.
Definition TNamed.cxx:112
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:457
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:543
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:501
The most important graphics class in the ROOT system.
Definition TPad.h:28
TPluginHandler * FindHandler(const char *base, const char *uri=nullptr)
Returns the handler if there exists a handler for the specified URI.
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
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.
Sequenceable collection abstract base class.
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:384
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:2384
virtual Int_t Sizeof() const
Returns size string will occupy on I/O buffer.
Definition TString.cxx:1407
Tree Input Dialog Widget.
Definition TTreeInput.h:22
A TTree represents a columnar dataset.
Definition TTree.h:89
static TClass * Class()
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual void Modified(Bool_t flag=1)=0
virtual Int_t YtoAbsPixel(Double_t y) const =0
virtual Double_t GetUymax() const =0
virtual TList * GetListOfPrimitives() const =0
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual Int_t XtoAbsPixel(Double_t x) const =0
virtual void Update()=0
virtual Double_t GetUxmax() const =0
virtual Double_t GetUymin() const =0
virtual Double_t GetUxmin() const =0
virtual TCanvas * GetCanvas() const =0
@ PAR_MIN
Definition CommonDefs.h:42
@ PAR_MAX
Definition CommonDefs.h:43
@ PAR_VAL
Definition CommonDefs.h:41
@ kFP_PRED1D
Definition CommonDefs.h:32
@ kFP_PQET
Definition CommonDefs.h:19
@ kFP_CLOSE
Definition CommonDefs.h:29
@ kFP_ADD
Definition CommonDefs.h:16
@ kFP_CHEB7
Definition CommonDefs.h:12
@ kFP_RESET
Definition CommonDefs.h:29
@ kFP_FILE
Definition CommonDefs.h:16
@ kFP_YMIN
Definition CommonDefs.h:20
@ kFP_UPDATE
Definition CommonDefs.h:29
@ kFP_MUSR
Definition CommonDefs.h:18
@ kFP_POL6
Definition CommonDefs.h:10
@ kFP_LGSL
Definition CommonDefs.h:22
@ kFP_XMIN
Definition CommonDefs.h:20
@ kFP_CHEB2
Definition CommonDefs.h:11
@ kFP_LMIN2
Definition CommonDefs.h:22
@ kFP_XYGAUS
Definition CommonDefs.h:13
@ kFP_CHEB6
Definition CommonDefs.h:12
@ kFP_MCHIS
Definition CommonDefs.h:18
@ kFP_MLINF
Definition CommonDefs.h:18
@ kFP_IMERR
Definition CommonDefs.h:17
@ kFP_POL1
Definition CommonDefs.h:9
@ kFP_POL5
Definition CommonDefs.h:9
@ kFP_LFUM
Definition CommonDefs.h:22
@ kFP_POL0
Definition CommonDefs.h:9
@ kFP_NOSEL
Definition CommonDefs.h:35
@ kFP_INTEG
Definition CommonDefs.h:17
@ kFP_DATAS
Definition CommonDefs.h:33
@ kFP_CHEB9
Definition CommonDefs.h:12
@ kFP_LAND
Definition CommonDefs.h:8
@ kFP_CHEB1
Definition CommonDefs.h:11
@ kFP_NONE
Definition CommonDefs.h:16
@ kFP_MLIST
Definition CommonDefs.h:18
@ 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:24
@ kFP_CHEB5
Definition CommonDefs.h:11
@ kFP_MITR
Definition CommonDefs.h:27
@ kFP_UFUNC
Definition CommonDefs.h:32
@ kFP_IFITR
Definition CommonDefs.h:17
@ kFP_BIGAUS
Definition CommonDefs.h:13
@ kFP_XYLANN
Definition CommonDefs.h:13
@ kFP_MINMETHOD
Definition CommonDefs.h:23
@ kFP_FLIST
Definition CommonDefs.h:8
@ kFP_TLIST
Definition CommonDefs.h:32
@ kFP_POL3
Definition CommonDefs.h:9
@ kFP_FIT
Definition CommonDefs.h:29
@ kFP_NORMADD
Definition CommonDefs.h:16
@ kFP_GAUSN
Definition CommonDefs.h:8
@ kFP_MTOL
Definition CommonDefs.h:27
@ kFP_CHEB8
Definition CommonDefs.h:12
@ kFP_CHEB3
Definition CommonDefs.h:11
@ kFP_FUMILI
Definition CommonDefs.h:23
@ kFP_RBUST
Definition CommonDefs.h:16
@ kFP_POL2
Definition CommonDefs.h:9
@ kFP_POL8
Definition CommonDefs.h:10
@ kFP_SIMPLX
Definition CommonDefs.h:22
@ kFP_PDEF
Definition CommonDefs.h:19
@ kFP_PRED2D
Definition CommonDefs.h:32
@ kFP_USERG
Definition CommonDefs.h:17
@ kFP_PARS
Definition CommonDefs.h:16
@ kFP_XYLAN
Definition CommonDefs.h:13
@ kFP_MBINL
Definition CommonDefs.h:18
@ kFP_ALTFUNC
Definition CommonDefs.h:36
@ kFP_DNOST
Definition CommonDefs.h:19
@ kFP_GSLLM
Definition CommonDefs.h:24
@ kFP_BFGS
Definition CommonDefs.h:24
@ kFP_MUBIN
Definition CommonDefs.h:18
@ kFP_CONV
Definition CommonDefs.h:16
@ kFP_GAUS
Definition CommonDefs.h:8
@ kFP_PVER
Definition CommonDefs.h:19
@ kFP_GALIB
Definition CommonDefs.h:25
@ kFP_LMIN
Definition CommonDefs.h:22
@ kFP_POL9
Definition CommonDefs.h:10
@ kFP_EMPW1
Definition CommonDefs.h:16
@ kFP_DNONE
Definition CommonDefs.h:19
@ kFP_GSLPR
Definition CommonDefs.h:24
@ kFP_USER
Definition CommonDefs.h:15
@ kFP_SCAN
Definition CommonDefs.h:25
@ kFP_LANDN
Definition CommonDefs.h:8
@ kFP_ALLW1
Definition CommonDefs.h:17
@ kFP_COMBINATION
Definition CommonDefs.h:23
@ kFP_XYEXP
Definition CommonDefs.h:13
@ kFP_GSLFR
Definition CommonDefs.h:24
@ kFP_BFGS2
Definition CommonDefs.h:24
@ kFP_ADDLS
Definition CommonDefs.h:17
@ kFP_DADVB
Definition CommonDefs.h:19
@ kFP_LGAS
Definition CommonDefs.h:22
@ kFP_MERR
Definition CommonDefs.h:27
@ kFP_PREVFIT
Definition CommonDefs.h:32
@ kFP_MIGRAD
Definition CommonDefs.h:22
@ kFP_TMVAGA
Definition CommonDefs.h:25
@ kFP_DSAME
Definition CommonDefs.h:19
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 ...
TLine l
Definition textangle.C:4