162 #include "RConfigure.h"
176 void SearchCanvases(TSeqCollection* canvases, std::vector<TObject*>& objects);
178 typedef std::multimap<TObject*, TF1*> FitFuncMap_t;
184 TF1* TFitEditor::FindFunction()
187 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
189 TString name(te->GetTitle());
192 if ( fTypeFit->GetSelected() == kFP_UFUNC ) {
193 for (
auto f : fSystemFuncs) {
194 if ( strcmp( f->GetName(), name ) == 0 )
200 }
else if ( fTypeFit->GetSelected() == kFP_PREVFIT ) {
201 std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(fFitObject);
202 for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
204 if ( strcmp( f->GetName(), name ) == 0 )
223 double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
226 if ( dynamic_cast<TF3 *>(f) != 0 ) {
227 TF3* fnew = (TF3 *)f->IsA()->New();
229 f->GetRange(xmin,ymin,zmin,xmax,ymax,zmax);
230 fnew->SetRange(xmin,ymin,zmin,xmax,ymax,zmax);
231 fnew->SetParent(
nullptr );
232 fnew->AddToGlobalList(
false);
234 }
else if ( dynamic_cast<TF2 *>(f) != 0 ) {
235 TF2* fnew = (TF2 *)f->IsA()->New();
237 f->GetRange(xmin,ymin,xmax,ymax);
238 fnew->SetRange(xmin,ymin,xmax,ymax);
239 fnew->Save(xmin,xmax,ymin,ymax,0,0);
240 fnew->SetParent(
nullptr );
241 fnew->AddToGlobalList(
false);
244 TF1* fnew = (TF1 *)f->IsA()->New();
246 f->GetRange(xmin,xmax);
247 fnew->SetRange(xmin,xmax);
250 if (
'\0' != fnew->GetExpFormula()[0] )
251 fnew->Save(xmin,xmax,0,0,0,0);
252 fnew->SetParent(
nullptr );
253 fnew->AddToGlobalList(
false);
261 void GetParameters(TFitEditor::FuncParams_t & pars, TF1* func)
263 int npar = func->GetNpar();
264 if (npar != (
int) pars.size() ) pars.resize(npar);
265 for ( Int_t i = 0; i < npar; ++i )
267 Double_t par_min, par_max;
268 pars[i][PAR_VAL] = func->GetParameter(i);
269 func->GetParLimits(i, par_min, par_max);
270 pars[i][PAR_MIN] = par_min;
271 pars[i][PAR_MAX] = par_max;
278 void SetParameters(TFitEditor::FuncParams_t & pars, TF1* func)
280 int npar = func->GetNpar();
281 if (npar > (
int) pars.size() ) pars.resize(npar);
282 for ( Int_t i = 0; i < npar; ++i )
284 func->SetParameter(i, pars[i][PAR_VAL]);
285 func->SetParLimits(i, pars[i][PAR_MIN], pars[i][PAR_MAX]);
292 template<
class FitObject>
293 void InitParameters(TF1* func, FitObject * fitobj)
295 const int special = func->GetNumber();
296 if (100 == special || 400 == special) {
297 ROOT::Fit::BinData data;
298 ROOT::Fit::FillData(data,fitobj,func);
299 ROOT::Fit::InitGaus(data, func);
301 }
else if ( 110 == special || 410 == special ) {
302 ROOT::Fit::BinData data;
303 ROOT::Fit::FillData(data,fitobj,func);
304 ROOT::Fit::Init2DGaus(data,func);
312 void GetTreeVarsAndCuts(TGComboBox* dataSet, TString& variablesStr, TString& cutsStr)
315 TGTextLBEntry* textEntry =
316 static_cast<TGTextLBEntry*
>( dataSet->GetListBox()->GetEntry( dataSet->GetSelected() ) );
317 if (!textEntry)
return;
319 TString nameStr ( textEntry->GetText()->GetString() );
321 variablesStr = nameStr(nameStr.First(
'(') + 2, nameStr.First(
',') - nameStr.First(
'(') - 3);
323 cutsStr = nameStr( nameStr.First(
',') + 3, nameStr.First(
')') - nameStr.First(
',') - 4 );
327 ClassImp(TFitEditor);
329 TFitEditor *TFitEditor::fgFitDialog = 0;
334 TFitEditor * TFitEditor::GetInstance(TVirtualPad* pad, TObject *obj)
340 gROOT->MakeDefCanvas();
345 fgFitDialog =
new TFitEditor(pad, obj);
347 fgFitDialog->Show(pad, obj);
356 TFitEditor::TFitEditor(TVirtualPad* pad, TObject *obj) :
357 TGMainFrame(gClient->GetRoot(), 20, 20),
367 fChangedParams (kFALSE)
369 fType = kObjectHisto;
370 SetCleanup(kDeepCleanup);
372 TGCompositeFrame *tf =
new TGCompositeFrame(
this, 350, 26,
374 TGLabel *label =
new TGLabel(tf,
"Data Set: ");
375 tf->AddFrame(label,
new TGLayoutHints(kLHintsNormal, 15, 0, 5, 0));
377 fDataSet =
new TGComboBox(tf, kFP_DATAS);
379 fDataSet->Resize(264, 20);
381 tf->AddFrame(fDataSet,
new TGLayoutHints(kLHintsNormal, 13, 0, 5, 0));
382 fDataSet->Associate(
this);
384 this->AddFrame(tf,
new TGLayoutHints(kLHintsNormal | kLHintsExpandX,0,0,5,5));
386 CreateFunctionGroup();
388 fTab =
new TGTab(
this, 10, 10);
389 AddFrame(fTab,
new TGLayoutHints(kLHintsExpandY | kLHintsExpandX));
390 fTab->SetCleanup(kDeepCleanup);
391 fTab->Associate(
this);
393 TGHorizontalFrame *cf1 =
new TGHorizontalFrame(
this, 350, 20, kFixedWidth);
394 cf1->SetCleanup(kDeepCleanup);
395 fUpdateButton =
new TGTextButton(cf1,
"&Update", kFP_UPDATE);
396 fUpdateButton->Associate(
this);
397 cf1->AddFrame(fUpdateButton,
new TGLayoutHints(kLHintsTop |
398 kLHintsExpandX, 0, 20, 2, 2));
401 fFitButton =
new TGTextButton(cf1,
"&Fit", kFP_FIT);
402 fFitButton->Associate(
this);
403 cf1->AddFrame(fFitButton,
new TGLayoutHints(kLHintsTop |
404 kLHintsExpandX, 15, -6, 2, 2));
406 fResetButton =
new TGTextButton(cf1,
"&Reset", kFP_RESET);
407 fResetButton->Associate(
this);
408 cf1->AddFrame(fResetButton,
new TGLayoutHints(kLHintsTop |
409 kLHintsExpandX, 11, -2, 2, 2));
411 fCloseButton =
new TGTextButton(cf1,
"&Close", kFP_CLOSE);
412 fCloseButton->Associate(
this);
413 cf1->AddFrame(fCloseButton,
new TGLayoutHints(kLHintsTop |
414 kLHintsExpandX, 7, 2, 2, 2));
415 AddFrame(cf1,
new TGLayoutHints(kLHintsNormal |
416 kLHintsRight, 0, 5, 5, 5));
419 int parts[] = { 20, 20, 20, 20, 20 };
420 fStatusBar =
new TGStatusBar(
this, 10, 10);
421 fStatusBar->SetParts(parts, 5);
422 AddFrame(fStatusBar,
new TGLayoutHints(kLHintsBottom |
427 CreateMinimizationTab();
429 gROOT->GetListOfCleanups()->Add(
this);
432 fGeneral->HideFrame(fSliderZParent);
435 TGDimension size = GetDefaultSize();
436 SetWindowName(
"Fit Panel");
437 SetIconName(
"Fit Panel");
438 SetClassHints(
"ROOT",
"Fit Panel");
440 SetMWMHints(kMWMDecorAll | kMWMDecorResizeH | kMWMDecorMaximize |
441 kMWMDecorMinimize | kMWMDecorMenu,
442 kMWMFuncAll | kMWMFuncResize | kMWMFuncMaximize |
448 GetFunctionsFromSystem();
451 TList* l =
new TList();
453 std::vector<TObject*> v;
454 SearchCanvases(l, v);
460 SetFitObject(pad, obj, kButton1Down);
470 SetCanvas(pad->GetCanvas());
472 pad->GetCanvas()->Selected(pad, obj, kButton1Down);
475 UInt_t dw = fClient->GetDisplayWidth();
479 if (pad && pad->GetCanvas() ) {
480 cw = pad->GetCanvas()->GetWindowWidth();
481 cx = (UInt_t)pad->GetCanvas()->GetWindowTopX();
482 cy = (UInt_t)pad->GetCanvas()->GetWindowTopY();
488 if (cw + size.fWidth < dw) {
489 Int_t gedx = 0, gedy = 0;
491 gedy = (cy > 20) ? cy-20 : 0;
492 MoveResize(gedx, gedy, size.fWidth, size.fHeight);
493 SetWMPosition(gedx, gedy);
496 gVirtualX->RaiseWindow(GetId());
498 ChangeOptions(GetOptions() | kFixedSize);
499 SetWMSize(size.fWidth, size.fHeight);
500 SetWMSizeHints(size.fWidth, size.fHeight, size.fWidth, size.fHeight, 0, 0);
506 TFitEditor::~TFitEditor()
511 fCloseButton ->Disconnect(
"Clicked()");
512 fDataSet ->Disconnect(
"Selected(Int_t)");
513 fUpdateButton->Disconnect(
"Clicked()");
514 TQObject::Disconnect(
"TCanvas",
"Selected(TVirtualPad *, TObject *, Int_t)",
515 this,
"SetFitObject(TVirtualPad *, TObject *, Int_t)");
516 gROOT->GetListOfCleanups()->Remove(
this);
524 if (fConvFunc)
delete fConvFunc;
525 if (fSumFunc)
delete fSumFunc;
528 for (
auto &entry : fPrevFit)
533 for (
auto func : fSystemFuncs)
535 fSystemFuncs.clear();
545 void TFitEditor::CreateFunctionGroup()
547 TGGroupFrame *gf1 =
new TGGroupFrame(
this,
"Fit Function", kFitWidth);
548 TGCompositeFrame *tf0 =
new TGCompositeFrame(gf1, 350, 26, kHorizontalFrame);
549 TGLabel *label1 =
new TGLabel(tf0,
"Type:");
550 tf0 -> AddFrame(label1,
new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0));
552 fTypeFit =
new TGComboBox(tf0, kFP_TLIST);
553 fTypeFit -> AddEntry(
"User Func", kFP_UFUNC);
554 fTypeFit -> AddEntry(
"Predef-1D", kFP_PRED1D);
555 fTypeFit -> Resize(90, 20);
556 fTypeFit -> Select(kFP_PRED1D, kFALSE);
558 TGListBox *lb = fTypeFit->GetListBox();
559 lb->Resize(lb->GetWidth(), 200);
560 tf0->AddFrame(fTypeFit,
new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
561 fTypeFit->Associate(
this);
563 fFuncList =
new TGComboBox(tf0, kFP_FLIST);
565 fFuncList->Resize(194, 20);
566 fFuncList->Select(kFP_GAUS, kFALSE);
568 lb = fFuncList->GetListBox();
569 lb -> Resize(lb->GetWidth(), 500);
570 tf0 -> AddFrame(fFuncList,
new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
571 fFuncList->Associate(
this);
573 gf1->AddFrame(tf0,
new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
575 TGCompositeFrame *tf1 =
new TGCompositeFrame(gf1, 350, 26, kHorizontalFrame);
576 TGHButtonGroup *bgr =
new TGHButtonGroup(tf1,
"Operation");
578 bgr -> SetRadioButtonExclusive();
579 fNone =
new TGRadioButton(bgr,
"Nop", kFP_NONE);
580 fAdd =
new TGRadioButton(bgr,
"Add", kFP_ADD);
581 fNormAdd =
new TGRadioButton(bgr,
"NormAdd", kFP_NORMADD);
582 fConv =
new TGRadioButton(bgr,
"Conv", kFP_CONV);
584 fNone -> SetToolTipText(
"No operation defined");
585 fNone -> SetState(kButtonDown, kFALSE);
586 fAdd -> SetToolTipText(
"Addition");
588 fNormAdd -> SetToolTipText(
"NormAddition");
590 fConv -> SetToolTipText(
"Convolution");
593 fLayoutNone =
new TGLayoutHints(kLHintsLeft,0 ,5,3,-10);
594 fLayoutAdd =
new TGLayoutHints(kLHintsLeft,10,5,3,-10);
595 fLayoutNormAdd =
new TGLayoutHints(kLHintsLeft,10,5,3,-10);
596 fLayoutConv =
new TGLayoutHints(kLHintsLeft,10,5,3,-10);
598 bgr -> SetLayoutHints(fLayoutNone, fNone);
599 bgr -> SetLayoutHints(fLayoutAdd, fAdd);
600 bgr -> SetLayoutHints(fLayoutNormAdd,fNormAdd);
601 bgr -> SetLayoutHints(fLayoutConv, fConv);
603 bgr -> ChangeOptions(kFitWidth | kHorizontalFrame);
605 tf1 -> AddFrame(bgr,
new TGLayoutHints(kLHintsExpandX, 0, 0, 3, 0));
606 gf1 -> AddFrame(tf1,
new TGLayoutHints(kLHintsExpandX));
608 TGCompositeFrame *tf2 =
new TGCompositeFrame(gf1, 350, 26,
610 fEnteredFunc =
new TGTextEntry(tf2,
new TGTextBuffer(0), kFP_FILE);
612 fEnteredFunc->SetAlignment(kTextLeft);
613 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
615 fEnteredFunc->SetText(te->GetTitle());
616 fEnteredFunc->SetToolTipText(
"Enter file_name/function_name or a function expression");
617 fEnteredFunc->Resize(250,fEnteredFunc->GetDefaultHeight());
618 tf2->AddFrame(fEnteredFunc,
new TGLayoutHints(kLHintsLeft |
620 kLHintsExpandX, 2, 2, 2, 2));
621 gf1->AddFrame(tf2,
new TGLayoutHints(kLHintsNormal |
622 kLHintsExpandX, 0, 0, 2, 0));
624 TGHorizontalFrame *s1 =
new TGHorizontalFrame(gf1);
625 TGLabel *label21 =
new TGLabel(s1,
"Selected: ");
626 s1->AddFrame(label21,
new TGLayoutHints(kLHintsNormal |
627 kLHintsCenterY, 2, 2, 2, 0));
628 TGHorizontal3DLine *hlines =
new TGHorizontal3DLine(s1);
629 s1->AddFrame(hlines,
new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
630 gf1->AddFrame(s1,
new TGLayoutHints(kLHintsExpandX));
632 TGCompositeFrame *tf4 =
new TGCompositeFrame(gf1, 350, 26,
634 TGTextLBEntry *txt = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
635 TString s = txt->GetTitle();
636 fSelLabel =
new TGLabel(tf4, s.Sizeof()>30?s(0,30)+
"...":s);
637 tf4->AddFrame(fSelLabel,
new TGLayoutHints(kLHintsNormal |
638 kLHintsCenterY, 0, 6, 2, 0));
640 gClient->GetColorByName(
"#336666", color);
641 fSelLabel->SetTextColor(color, kFALSE);
642 TGCompositeFrame *tf5 =
new TGCompositeFrame(tf4, 120, 20,
643 kHorizontalFrame | kFixedWidth);
644 fSetParam =
new TGTextButton(tf5,
"Set Parameters...", kFP_PARS);
645 tf5->AddFrame(fSetParam,
new TGLayoutHints(kLHintsRight |
648 fSetParam->SetToolTipText(
"Open a dialog for parameter(s) settings");
649 tf4->AddFrame(tf5,
new TGLayoutHints(kLHintsRight |
650 kLHintsTop, 5, 0, 2, 2));
651 gf1->AddFrame(tf4,
new TGLayoutHints(kLHintsNormal |
652 kLHintsExpandX, 5, 0, 0, 0));
654 this->AddFrame(gf1,
new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
661 void TFitEditor::CreateGeneralTab()
663 fTabContainer = fTab->AddTab(
"General");
664 fGeneral =
new TGCompositeFrame(fTabContainer, 10, 10, kVerticalFrame);
665 fTabContainer->AddFrame(fGeneral,
new TGLayoutHints(kLHintsTop |
670 TGGroupFrame *gf =
new TGGroupFrame(fGeneral,
"Fit Settings", kFitWidth);
673 TGHorizontalFrame *h1 =
new TGHorizontalFrame(gf);
674 TGLabel *label4 =
new TGLabel(h1,
"Method");
675 h1->AddFrame(label4,
new TGLayoutHints(kLHintsNormal |
676 kLHintsCenterY, 2, 2, 0, 0));
677 TGHorizontal3DLine *hline1 =
new TGHorizontal3DLine(h1);
678 h1->AddFrame(hline1,
new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
679 gf->AddFrame(h1,
new TGLayoutHints(kLHintsExpandX));
681 TGHorizontalFrame *h2 =
new TGHorizontalFrame(gf);
682 TGVerticalFrame *v1 =
new TGVerticalFrame(h2);
683 fMethodList = BuildMethodList(v1, kFP_MLIST);
684 fMethodList->Select(1, kFALSE);
685 fMethodList->Resize(140, 20);
686 TGListBox *lb = fMethodList->GetListBox();
687 Int_t lbe = lb->GetNumberOfEntries();
688 lb->Resize(lb->GetWidth(), lbe*16);
689 v1->AddFrame(fMethodList,
new TGLayoutHints(kLHintsLeft, 0, 0, 2, 5));
691 fLinearFit =
new TGCheckButton(v1,
"Linear fit", kFP_MLINF);
692 fLinearFit->Associate(
this);
693 fLinearFit->SetToolTipText(
"Perform Linear fitter if selected");
694 v1->AddFrame(fLinearFit,
new TGLayoutHints(kLHintsNormal, 0, 0, 8, 2));
697 h2->AddFrame(v1,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
699 TGVerticalFrame *v2 =
new TGVerticalFrame(h2);
700 TGCompositeFrame *v21 =
new TGCompositeFrame(v2, 120, 20,
701 kHorizontalFrame | kFixedWidth);
702 fUserButton =
new TGTextButton(v21,
"User-Defined...", kFP_MUSR);
703 v21->AddFrame(fUserButton,
new TGLayoutHints(kLHintsRight |
706 fUserButton->SetToolTipText(
"Open a dialog for entering a user-defined method");
707 fUserButton->SetState(kButtonDisabled);
708 v2->AddFrame(v21,
new TGLayoutHints(kLHintsRight | kLHintsTop));
710 TGHorizontalFrame *v1h =
new TGHorizontalFrame(v2);
711 fEnableRobust =
new TGCheckButton(v1h,
"Robust:", -1);
712 fEnableRobust->Associate(
this);
713 fEnableRobust->SetToolTipText(
"Perform Linear Robust fitter if selected");
714 v1h->AddFrame(fEnableRobust,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
715 fRobustValue =
new TGNumberEntry(v1h, 0.95, 5, kFP_RBUST,
716 TGNumberFormat::kNESRealTwo,
717 TGNumberFormat::kNEAPositive,
718 TGNumberFormat::kNELLimitMinMax,0.,0.99);
719 v1h->AddFrame(fRobustValue,
new TGLayoutHints(kLHintsLeft));
720 v2->AddFrame(v1h,
new TGLayoutHints(kLHintsNormal, 0, 0, 12, 2));
721 fRobustValue->SetState(kFALSE);
722 fRobustValue->GetNumberEntry()->SetToolTipText(
"Available only for graphs");
730 h2->AddFrame(v2,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 20, 0, 0, 0));
731 gf->AddFrame(h2,
new TGLayoutHints(kLHintsExpandX, 20, 0, 0, 0));
734 TGHorizontalFrame *h3 =
new TGHorizontalFrame(gf);
735 TGLabel *label5 =
new TGLabel(h3,
"Fit Options");
736 h3->AddFrame(label5,
new TGLayoutHints(kLHintsNormal |
737 kLHintsCenterY, 2, 2, 0, 0));
738 TGHorizontal3DLine *hline2 =
new TGHorizontal3DLine(h3);
739 h3->AddFrame(hline2,
new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
740 gf->AddFrame(h3,
new TGLayoutHints(kLHintsExpandX));
742 TGHorizontalFrame *h =
new TGHorizontalFrame(gf);
743 TGVerticalFrame *v3 =
new TGVerticalFrame(h);
744 fIntegral =
new TGCheckButton(v3,
"Integral", kFP_INTEG);
745 fIntegral->Associate(
this);
746 fIntegral->SetToolTipText(
"'I'- use integral of function instead of value in bin center");
747 v3->AddFrame(fIntegral,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
749 fBestErrors =
new TGCheckButton(v3,
"Best errors", kFP_IMERR);
750 fBestErrors->Associate(
this);
751 fBestErrors->SetToolTipText(
"'E'- better errors estimation using Minos technique");
752 v3->AddFrame(fBestErrors,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
754 fAllWeights1 =
new TGCheckButton(v3,
"All weights = 1", kFP_ALLW1);
755 fAllWeights1->Associate(
this);
756 fAllWeights1->SetToolTipText(
"'W'- all weights=1 for non empty bins; error bars ignored");
757 v3->AddFrame(fAllWeights1,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
759 fEmptyBinsWghts1 =
new TGCheckButton(v3,
"Empty bins, weights=1", kFP_EMPW1);
760 fEmptyBinsWghts1->Associate(
this);
761 fEmptyBinsWghts1->SetToolTipText(
"'WW'- all weights=1 including empty bins; error bars ignored");
762 v3->AddFrame(fEmptyBinsWghts1,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
764 h->AddFrame(v3,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
766 TGVerticalFrame *v4 =
new TGVerticalFrame(h);
767 fUseRange =
new TGCheckButton(v4,
"Use range", kFP_USERG);
768 fUseRange->Associate(
this);
769 fUseRange->SetToolTipText(
"'R'- fit only data within the specified function range");
770 v4->AddFrame(fUseRange,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
772 fImproveResults =
new TGCheckButton(v4,
"Improve fit results", kFP_IFITR);
773 fImproveResults->Associate(
this);
774 fImproveResults->SetToolTipText(
"'M'- after minimum is found, search for a new one");
775 v4->AddFrame(fImproveResults,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
777 fAdd2FuncList =
new TGCheckButton(v4,
"Add to list", kFP_ADDLS);
778 fAdd2FuncList->Associate(
this);
779 fAdd2FuncList->SetToolTipText(
"'+'- add function to the list without deleting the previous");
780 v4->AddFrame(fAdd2FuncList,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
782 fUseGradient =
new TGCheckButton(v4,
"Use Gradient", kFP_ADDLS);
783 fUseGradient->Associate(
this);
784 fUseGradient->SetToolTipText(
"'G'- Use the gradient as an aid for the fitting");
785 v4->AddFrame(fUseGradient,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
787 h->AddFrame(v4,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 20, 0, 0, 0));
788 gf->AddFrame(h,
new TGLayoutHints(kLHintsExpandX, 20, 0, 0, 0));
791 TGHorizontalFrame *h5 =
new TGHorizontalFrame(gf);
792 TGLabel *label6 =
new TGLabel(h5,
"Draw Options");
793 h5->AddFrame(label6,
new TGLayoutHints(kLHintsNormal |
794 kLHintsCenterY, 2, 2, 2, 2));
795 TGHorizontal3DLine *hline3 =
new TGHorizontal3DLine(h5);
796 h5->AddFrame(hline3,
new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
797 gf->AddFrame(h5,
new TGLayoutHints(kLHintsExpandX));
799 TGHorizontalFrame *h6 =
new TGHorizontalFrame(gf);
800 TGVerticalFrame *v5 =
new TGVerticalFrame(h6);
802 fDrawSame =
new TGCheckButton(v5,
"SAME", kFP_DSAME);
803 fDrawSame->Associate(
this);
804 fDrawSame->SetToolTipText(
"Superimpose on previous picture in the same pad");
805 v5->AddFrame(fDrawSame,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
807 fNoDrawing =
new TGCheckButton(v5,
"No drawing", kFP_DNONE);
808 fNoDrawing->Associate(
this);
809 fNoDrawing->SetToolTipText(
"'0'- do not draw function graphics");
810 v5->AddFrame(fNoDrawing,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
812 fNoStoreDrawing =
new TGCheckButton(v5,
"Do not store/draw", kFP_DNOST);
813 fNoStoreDrawing->Associate(
this);
814 fNoStoreDrawing->SetToolTipText(
"'N'- do not store the function, do not draw it");
815 v5->AddFrame(fNoStoreDrawing,
new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
817 h6->AddFrame(v5,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
819 TGVerticalFrame *v6 =
new TGVerticalFrame(h6);
820 TGCompositeFrame *v61 =
new TGCompositeFrame(v6, 120, 20,
821 kHorizontalFrame | kFixedWidth);
822 fDrawAdvanced =
new TGTextButton(v61,
"&Advanced...", kFP_DADVB);
823 v61->AddFrame(fDrawAdvanced,
new TGLayoutHints(kLHintsRight |
826 fDrawAdvanced->SetToolTipText(
"Open a dialog for advanced draw options");
827 fDrawAdvanced->SetState(kButtonDisabled);
829 v6->AddFrame(v61,
new TGLayoutHints(kLHintsRight | kLHintsTop,
830 0, 0, (4+fDrawSame->GetHeight())*2, 0));
832 h6->AddFrame(v6,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
833 gf->AddFrame(h6,
new TGLayoutHints(kLHintsExpandX, 20, 0, 2, 0));
835 fGeneral->AddFrame(gf,
new TGLayoutHints(kLHintsExpandX |
836 kLHintsExpandY, 5, 5, 0, 0));
838 fSliderXParent =
new TGHorizontalFrame(fGeneral);
839 TGLabel *label8 =
new TGLabel(fSliderXParent,
"X");
840 fSliderXParent->AddFrame(label8,
new TGLayoutHints(kLHintsLeft |
841 kLHintsCenterY, 0, 5, 0, 0));
843 fSliderXMin =
new TGNumberEntry(fSliderXParent, 0, 5, kFP_XMIN,
844 TGNumberFormat::kNESRealTwo,
845 TGNumberFormat::kNEAAnyNumber,
846 TGNumberFormat::kNELLimitMinMax, -1,1);
847 fSliderXParent->AddFrame(fSliderXMin,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY));
849 fSliderX =
new TGDoubleHSlider(fSliderXParent, 1, kDoubleScaleBoth);
850 fSliderX->SetScale(5);
851 fSliderXParent->AddFrame(fSliderX,
new TGLayoutHints(kLHintsExpandX | kLHintsCenterY));
854 fSliderXMax =
new TGNumberEntry(fSliderXParent, 0, 5, kFP_XMIN,
855 TGNumberFormat::kNESRealTwo,
856 TGNumberFormat::kNEAAnyNumber,
857 TGNumberFormat::kNELLimitMinMax, -1,1);
858 fSliderXParent->AddFrame(fSliderXMax,
new TGLayoutHints(kLHintsRight | kLHintsCenterY));
859 fGeneral->AddFrame(fSliderXParent,
new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
862 fSliderYParent =
new TGHorizontalFrame(fGeneral);
863 TGLabel *label9 =
new TGLabel(fSliderYParent,
"Y");
864 fSliderYParent->AddFrame(label9,
new TGLayoutHints(kLHintsLeft |
865 kLHintsCenterY, 0, 5, 0, 0));
867 fSliderYMin =
new TGNumberEntry(fSliderYParent, 0, 5, kFP_YMIN,
868 TGNumberFormat::kNESRealTwo,
869 TGNumberFormat::kNEAAnyNumber,
870 TGNumberFormat::kNELLimitMinMax, -1,1);
871 fSliderYParent->AddFrame(fSliderYMin,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY));
873 fSliderY =
new TGDoubleHSlider(fSliderYParent, 1, kDoubleScaleBoth);
874 fSliderY->SetScale(5);
875 fSliderYParent->AddFrame(fSliderY,
new TGLayoutHints(kLHintsExpandX | kLHintsCenterY));
877 fSliderYMax =
new TGNumberEntry(fSliderYParent, 0, 5, kFP_YMIN,
878 TGNumberFormat::kNESRealTwo,
879 TGNumberFormat::kNEAAnyNumber,
880 TGNumberFormat::kNELLimitMinMax, -1,1);
881 fSliderYParent->AddFrame(fSliderYMax,
new TGLayoutHints(kLHintsRight | kLHintsCenterY));
882 fGeneral->AddFrame(fSliderYParent,
new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
885 fSliderZParent =
new TGHorizontalFrame(fGeneral);
886 TGLabel *label10 =
new TGLabel(fSliderZParent,
"Z:");
887 fSliderZParent->AddFrame(label10,
new TGLayoutHints(kLHintsLeft |
888 kLHintsCenterY, 0, 5, 0, 0));
889 fSliderZ =
new TGDoubleHSlider(fSliderZParent, 1, kDoubleScaleBoth);
890 fSliderZ->SetScale(5);
891 fSliderZParent->AddFrame(fSliderZ,
new TGLayoutHints(kLHintsExpandX |
893 fGeneral->AddFrame(fSliderZParent,
new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
900 void TFitEditor::CreateMinimizationTab()
902 fTabContainer = fTab->AddTab(
"Minimization");
903 fMinimization =
new TGCompositeFrame(fTabContainer, 10, 10, kVerticalFrame);
904 fTabContainer->AddFrame(fMinimization,
new TGLayoutHints(kLHintsTop |
907 MakeTitle(fMinimization,
"Library");
909 TGHorizontalFrame *hl =
new TGHorizontalFrame(fMinimization);
910 fLibMinuit =
new TGRadioButton(hl,
"Minuit", kFP_LMIN);
911 fLibMinuit->Associate(
this);
912 fLibMinuit->SetToolTipText(
"Use minimization from libMinuit (default)");
913 hl->AddFrame(fLibMinuit,
new TGLayoutHints(kLHintsNormal, 40, 0, 0, 1));
914 fStatusBar->SetText(
"LIB Minuit",1);
916 fLibMinuit2 =
new TGRadioButton(hl,
"Minuit2", kFP_LMIN2);
917 fLibMinuit2->Associate(
this);
918 fLibMinuit2->SetToolTipText(
"New C++ version of Minuit");
919 hl->AddFrame(fLibMinuit2,
new TGLayoutHints(kLHintsNormal, 35, 0, 0, 1));
921 fLibFumili =
new TGRadioButton(hl,
"Fumili", kFP_LFUM);
922 fLibFumili->Associate(
this);
923 fLibFumili->SetToolTipText(
"Use minimization from libFumili");
924 hl->AddFrame(fLibFumili,
new TGLayoutHints(kLHintsNormal, 30, 0, 0, 1));
925 fMinimization->AddFrame(hl,
new TGLayoutHints(kLHintsExpandX, 20, 0, 5, 1));
927 TGHorizontalFrame *hl2 =
new TGHorizontalFrame(fMinimization);
929 fLibGSL =
new TGRadioButton(hl2,
"GSL", kFP_LGSL);
930 #ifdef R__HAS_MATHMORE
931 fLibGSL->Associate(
this);
932 fLibGSL->SetToolTipText(
"Use minimization from libGSL");
934 fLibGSL->SetState(kButtonDisabled);
935 fLibGSL->SetToolTipText(
"Needs GSL to be compiled");
937 hl2->AddFrame(fLibGSL,
new TGLayoutHints(kLHintsNormal, 40, 0, 0, 1));
939 fLibGenetics =
new TGRadioButton(hl2,
"Genetics", kFP_LGAS);
940 if (gPluginMgr->FindHandler(
"ROOT::Math::Minimizer",
"Genetic") ||
941 gPluginMgr->FindHandler(
"ROOT::Math::Minimizer",
"GAlibMin") )
943 fLibGenetics->Associate(
this);
944 fLibGenetics->SetToolTipText(
"Different GAs implementations");
946 fLibGenetics->SetState(kButtonDisabled);
947 fLibGenetics->SetToolTipText(
"Needs any of the genetic"
948 "minimizers to be compiled");
950 hl2->AddFrame(fLibGenetics,
new TGLayoutHints(kLHintsNormal, 45, 0, 0, 1));
952 fMinimization->AddFrame(hl2,
new TGLayoutHints(kLHintsExpandX, 20, 0, 5, 1));
954 MakeTitle(fMinimization,
"Method");
956 TGHorizontalFrame *hm0 =
new TGHorizontalFrame(fMinimization);
957 fMinMethodList =
new TGComboBox(hm0, kFP_MINMETHOD);
958 fMinMethodList->Resize(290, 20);
959 fMinMethodList->Select(kFP_GAUS, kFALSE);
961 TGListBox *lb = fMinMethodList->GetListBox();
962 lb->Resize(lb->GetWidth(), 500);
963 fMinMethodList->Associate(
this);
965 hm0->AddFrame(fMinMethodList,
new TGLayoutHints(kLHintsNormal));
966 fMinimization->AddFrame(hm0,
new TGLayoutHints(kLHintsExpandX, 60, 0, 5, 1));
969 if ( ROOT::Math::MinimizerOptions::DefaultMinimizerType() ==
"Fumili" ) {
970 fLibFumili->SetState(kButtonDown);
971 }
else if ( ROOT::Math::MinimizerOptions::DefaultMinimizerType() ==
"Minuit" ) {
972 fLibMinuit->SetState(kButtonDown);
974 fLibMinuit2->SetState(kButtonDown);
978 MakeTitle(fMinimization,
"Settings");
979 TGLabel *hslabel1 =
new TGLabel(fMinimization,
"Use ENTER key to validate a new value or click");
980 fMinimization->AddFrame(hslabel1,
new TGLayoutHints(kLHintsNormal, 61, 0, 5, 1));
981 TGLabel *hslabel2 =
new TGLabel(fMinimization,
"on Reset button to set the defaults.");
982 fMinimization->AddFrame(hslabel2,
new TGLayoutHints(kLHintsNormal, 61, 0, 1, 10));
984 TGHorizontalFrame *hs =
new TGHorizontalFrame(fMinimization);
986 TGVerticalFrame *hsv1 =
new TGVerticalFrame(hs, 180, 10, kFixedWidth);
987 TGLabel *errlabel =
new TGLabel(hsv1,
"Error definition (default = 1): ");
988 hsv1->AddFrame(errlabel,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
990 TGLabel *tollabel =
new TGLabel(hsv1,
"Max tolerance (precision): ");
991 hsv1->AddFrame(tollabel,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
993 TGLabel *itrlabel =
new TGLabel(hsv1,
"Max number of iterations: ");
994 hsv1->AddFrame(itrlabel,
new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
996 hs->AddFrame(hsv1,
new TGLayoutHints(kLHintsNormal, 60, 0, 0, 0));
998 TGVerticalFrame *hsv2 =
new TGVerticalFrame(hs, 90,10, kFixedWidth);
999 fErrorScale =
new TGNumberEntryField(hsv2, kFP_MERR, ROOT::Math::MinimizerOptions::DefaultErrorDef(),
1000 TGNumberFormat::kNESRealTwo,
1001 TGNumberFormat::kNEAPositive,
1002 TGNumberFormat::kNELLimitMinMax,0.,100.);
1003 hsv2->AddFrame(fErrorScale,
new TGLayoutHints(kLHintsLeft | kLHintsExpandX,
1005 fTolerance =
new TGNumberEntryField(hsv2, kFP_MTOL, ROOT::Math::MinimizerOptions::DefaultTolerance(),
1006 TGNumberFormat::kNESReal,
1007 TGNumberFormat::kNEAPositive,
1008 TGNumberFormat::kNELLimitMinMax, 0., 1.);
1009 fTolerance->SetNumber(ROOT::Math::MinimizerOptions::DefaultTolerance());
1010 hsv2->AddFrame(fTolerance,
new TGLayoutHints(kLHintsLeft | kLHintsExpandX,
1012 fIterations =
new TGNumberEntryField(hsv2, kFP_MITR, 5000,
1013 TGNumberFormat::kNESInteger,
1014 TGNumberFormat::kNEAPositive,
1015 TGNumberFormat::kNELNoLimits);
1016 fIterations->SetNumber(ROOT::Math::MinimizerOptions::DefaultMaxIterations());
1017 hsv2->AddFrame(fIterations,
new TGLayoutHints(kLHintsLeft | kLHintsExpandX,
1019 hs->AddFrame(hsv2,
new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
1020 fMinimization->AddFrame(hs,
new TGLayoutHints(kLHintsExpandX, 0, 0, 1, 1));
1021 fStatusBar->SetText(Form(
"Itr: %d",ROOT::Math::MinimizerOptions::DefaultMaxIterations()),3);
1023 MakeTitle(fMinimization,
"Print Options");
1025 TGHorizontalFrame *h8 =
new TGHorizontalFrame(fMinimization);
1026 fOptDefault =
new TGRadioButton(h8,
"Default", kFP_PDEF);
1027 fOptDefault->Associate(
this);
1028 fOptDefault->SetToolTipText(
"Default is between Verbose and Quiet");
1029 h8->AddFrame(fOptDefault,
new TGLayoutHints(kLHintsNormal, 40, 0, 0, 1));
1030 fOptDefault->SetState(kButtonDown);
1031 fStatusBar->SetText(
"Prn: DEF",4);
1033 fOptVerbose =
new TGRadioButton(h8,
"Verbose", kFP_PVER);
1034 fOptVerbose->Associate(
this);
1035 fOptVerbose->SetToolTipText(
"'V'- print results after each iteration");
1036 h8->AddFrame(fOptVerbose,
new TGLayoutHints(kLHintsNormal, 30, 0, 0, 1));
1038 fOptQuiet =
new TGRadioButton(h8,
"Quiet", kFP_PQET);
1039 fOptQuiet->Associate(
this);
1040 fOptQuiet->SetToolTipText(
"'Q'- no print");
1041 h8->AddFrame(fOptQuiet,
new TGLayoutHints(kLHintsNormal, 25, 0, 0, 1));
1043 fMinimization->AddFrame(h8,
new TGLayoutHints(kLHintsExpandX, 20, 0, 5, 1));
1050 void TFitEditor::ConnectSlots()
1053 fDataSet -> Connect(
"Selected(Int_t)",
"TFitEditor",
this,
"DoDataSet(Int_t)");
1055 fTypeFit -> Connect(
"Selected(Int_t)",
"TFitEditor",
this,
"FillFunctionList(Int_t)");
1057 fFuncList -> Connect(
"Selected(Int_t)",
"TFitEditor",
this,
"DoFunction(Int_t)");
1059 fEnteredFunc -> Connect(
"ReturnPressed()",
"TFitEditor",
this,
"DoEnteredFunction()");
1061 fSetParam -> Connect(
"Clicked()",
"TFitEditor",
this,
"DoSetParameters()");
1063 fAdd -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoAddition(Bool_t)");
1067 fAllWeights1 -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoAllWeights1()");
1068 fUseRange -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoUseFuncRange()");
1069 fEmptyBinsWghts1 -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoEmptyBinsAllWeights1()");
1071 fLinearFit -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoLinearFit()");
1072 fEnableRobust -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoRobustFit()");
1075 fNoStoreDrawing -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoNoStoreDrawing()");
1077 fUpdateButton -> Connect(
"Clicked()",
"TFitEditor",
this,
"DoUpdate()");
1078 fFitButton -> Connect(
"Clicked()",
"TFitEditor",
this,
"DoFit()");
1079 fResetButton -> Connect(
"Clicked()",
"TFitEditor",
this,
"DoReset()");
1080 fCloseButton -> Connect(
"Clicked()",
"TFitEditor",
this,
"DoClose()");
1082 fUserButton -> Connect(
"Clicked()",
"TFitEditor",
this,
"DoUserDialog()");
1084 fDrawAdvanced -> Connect(
"Clicked()",
"TFitEditor",
this,
"DoAdvancedOptions()");
1086 if (fType != kObjectTree)
1088 fSliderX -> Connect(
"PositionChanged()",
"TFitEditor",
this,
"DoSliderXMoved()");
1089 fSliderXMax -> Connect(
"ValueSet(Long_t)",
"TFitEditor",
this,
"DoNumericSliderXChanged()");
1090 fSliderXMin -> Connect(
"ValueSet(Long_t)",
"TFitEditor",
this,
"DoNumericSliderXChanged()");
1094 fSliderY -> Connect(
"PositionChanged()",
"TFitEditor",
this,
"DoSliderYMoved()");
1095 fSliderYMax -> Connect(
"ValueSet(Long_t)",
"TFitEditor",
this,
"DoNumericSliderYChanged()");
1096 fSliderYMin -> Connect(
"ValueSet(Long_t)",
"TFitEditor",
this,
"DoNumericSliderYChanged()");
1099 fSliderZ -> Connect(
"PositionChanged()",
"TFitEditor",
this,
"DoSliderZMoved()");
1102 fParentPad -> Connect(
"RangeAxisChanged()",
"TFitEditor",
this,
"UpdateGUI()");
1105 fLibMinuit -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoLibrary(Bool_t)");
1106 fLibMinuit2 -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoLibrary(Bool_t)");
1107 fLibFumili -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoLibrary(Bool_t)");
1108 fLibGSL -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoLibrary(Bool_t)");
1109 fLibGenetics -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoLibrary(Bool_t)");
1112 fMinMethodList -> Connect(
"Selected(Int_t)",
"TFitEditor",
this,
"DoMinMethod(Int_t)");
1114 fIterations -> Connect(
"ReturnPressed()",
"TFitEditor",
this,
"DoMaxIterations()");
1116 fOptDefault -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoPrintOpt(Bool_t)");
1117 fOptVerbose -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoPrintOpt(Bool_t)");
1118 fOptQuiet -> Connect(
"Toggled(Bool_t)",
"TFitEditor",
this,
"DoPrintOpt(Bool_t)");
1125 void TFitEditor::DisconnectSlots()
1127 Disconnect(
"CloseWindow()");
1129 fFuncList -> Disconnect(
"Selected(Int_t)");
1130 fEnteredFunc -> Disconnect(
"ReturnPressed()");
1131 fSetParam -> Disconnect(
"Clicked()");
1132 fAdd -> Disconnect(
"Toggled(Bool_t)");
1137 fAllWeights1 -> Disconnect(
"Toggled(Bool_t)");
1138 fEmptyBinsWghts1 -> Disconnect(
"Toggled(Bool_t)");
1141 fLinearFit -> Disconnect(
"Toggled(Bool_t)");
1142 fEnableRobust -> Disconnect(
"Toggled(Bool_t)");
1146 fNoStoreDrawing -> Disconnect(
"Toggled(Bool_t)");
1149 fFitButton -> Disconnect(
"Clicked()");
1150 fResetButton -> Disconnect(
"Clicked()");
1153 fUserButton -> Disconnect(
"Clicked()");
1154 fDrawAdvanced -> Disconnect(
"Clicked()");
1156 if (fType != kObjectTree)
1158 fSliderX -> Disconnect(
"PositionChanged()");
1159 fSliderXMax -> Disconnect(
"ValueChanged(Long_t)");
1160 fSliderXMin -> Disconnect(
"ValueChanged(Long_t)");
1164 fSliderY -> Disconnect(
"PositionChanged()");
1165 fSliderYMax -> Disconnect(
"ValueChanged(Long_t)");
1166 fSliderYMin -> Disconnect(
"ValueChanged(Long_t)");
1169 fSliderZ -> Disconnect(
"PositionChanged()");
1171 fLibMinuit -> Disconnect(
"Toggled(Bool_t)");
1172 fLibMinuit2 -> Disconnect(
"Toggled(Bool_t)");
1173 fLibFumili -> Disconnect(
"Toggled(Bool_t)");
1174 fLibGSL -> Disconnect(
"Toggled(Bool_t)");
1175 fLibGenetics -> Disconnect(
"Toggled(Bool_t)");
1177 fMinMethodList -> Disconnect(
"Selected(Int_t)");
1179 fIterations -> Disconnect(
"ReturnPressed()");
1181 fOptDefault -> Disconnect(
"Toggled(Bool_t)");
1182 fOptVerbose -> Disconnect(
"Toggled(Bool_t)");
1183 fOptQuiet -> Disconnect(
"Toggled(Bool_t)");
1190 void TFitEditor::SetCanvas(TCanvas * )
1203 TQObject::Connect(
"TCanvas",
"Selected(TVirtualPad *, TObject *, Int_t)",
1205 "SetFitObject(TVirtualPad *, TObject *, Int_t)");
1206 TQObject::Connect(
"TCanvas",
"Closed()",
"TFitEditor",
this,
"DoNoSelection()");
1212 void TFitEditor::Hide()
1215 fgFitDialog->UnmapWindow();
1218 fParentPad->Disconnect(
"RangeAxisChanged()");
1220 TQObject::Disconnect(
"TCanvas",
"Selected(TVirtualPad *, TObject *, Int_t)",
1221 this,
"SetFitObject(TVirtualPad *, TObject *, Int_t)");
1225 gROOT->GetListOfCleanups()->Remove(
this);
1231 void TFitEditor::Show(TVirtualPad* pad, TObject *obj)
1233 if (!gROOT->GetListOfCleanups()->FindObject(
this))
1234 gROOT->GetListOfCleanups()->Add(
this);
1236 if (!fgFitDialog->IsMapped()) {
1237 fgFitDialog->MapWindow();
1238 gVirtualX->RaiseWindow(GetId());
1240 fParentPad =
static_cast<TPad*
>(pad);
1241 SetCanvas(pad->GetCanvas());
1242 SetFitObject(pad, obj, kButton1Down);
1248 void TFitEditor::CloseWindow()
1263 void TFitEditor::Terminate()
1265 TQObject::Disconnect(
"TCanvas",
"Closed()");
1273 void TFitEditor::UpdateGUI()
1275 if (!fFitObject)
return;
1277 DrawSelection(
true);
1279 if ( fType == kObjectTree )
1285 if (fType != kObjectTree) {
1289 hist = (TH1*)fFitObject;
1293 hist = ((TGraph*)fFitObject)->GetHistogram();
1296 case kObjectMultiGraph:
1297 hist = ((TMultiGraph*)fFitObject)->GetHistogram();
1300 case kObjectGraph2D:
1301 hist = ((TGraph2D*)fFitObject)->GetHistogram(
"empty");
1305 hist = (TH1 *)((THStack *)fFitObject)->GetHists()->First();
1314 Error(
"UpdateGUI",
"No hist is present - this should not happen, please report."
1315 "The FitPanel might be in an inconsistent state");
1320 fSliderX->Disconnect(
"PositionChanged()");
1321 fSliderXMin->Disconnect(
"ValueChanged()");
1322 fSliderXMax->Disconnect(
"ValueChanged()");
1324 if (!fSliderXParent->IsMapped())
1325 fSliderXParent->MapWindow();
1327 fXaxis = hist->GetXaxis();
1328 fYaxis = hist->GetYaxis();
1329 fZaxis = hist->GetZaxis();
1330 Int_t ixrange = fXaxis->GetNbins();
1331 Int_t ixmin = fXaxis->GetFirst();
1332 Int_t ixmax = fXaxis->GetLast();
1334 if (ixmin > 1 || ixmax < ixrange) {
1335 fSliderX->SetRange(ixmin,ixmax);
1336 fSliderX->SetPosition(ixmin, ixmax);
1338 fSliderX->SetRange(1,ixrange);
1339 fSliderX->SetPosition(ixmin,ixmax);
1342 fSliderX->SetScale(5);
1344 fSliderXMin->SetLimits(TGNumberFormat::kNELLimitMinMax,
1345 fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ),
1346 fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
1347 fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ));
1348 fSliderXMax->SetLimits(TGNumberFormat::kNELLimitMinMax,
1349 fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ),
1350 fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
1351 fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
1353 fSliderX->Connect(
"PositionChanged()",
"TFitEditor",
this,
"DoSliderXMoved()");
1354 fSliderXMax->Connect(
"ValueSet(Long_t)",
"TFitEditor",
this,
"DoNumericSliderXChanged()");
1355 fSliderXMin->Connect(
"ValueSet(Long_t)",
"TFitEditor",
this,
"DoNumericSliderXChanged()");
1359 fSliderY->Disconnect(
"PositionChanged()");
1360 fSliderYMin->Disconnect(
"ValueChanged()");
1361 fSliderYMax->Disconnect(
"ValueChanged()");
1363 if (!fSliderYParent->IsMapped())
1364 fSliderYParent->MapWindow();
1365 if (fSliderZParent->IsMapped())
1366 fSliderZParent->UnmapWindow();
1368 Int_t iymin = 0, iymax = 0, iyrange = 0;
1371 case kObjectGraph2D:
1373 iyrange = fYaxis->GetNbins();
1374 iymin = fYaxis->GetFirst();
1375 iymax = fYaxis->GetLast();
1379 case kObjectMultiGraph:
1386 if (iymin > 1 || iymax < iyrange) {
1387 fSliderY->SetRange(iymin,iymax);
1388 fSliderY->SetPosition(iymin, iymax);
1390 fSliderY->SetRange(1,iyrange);
1391 fSliderY->SetPosition(iymin,iymax);
1394 fSliderY->SetScale(5);
1396 fSliderYMin->SetLimits(TGNumberFormat::kNELLimitMinMax,
1397 fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ),
1398 fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
1399 fSliderYMin->SetNumber(fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ));
1400 fSliderYMax->SetLimits(TGNumberFormat::kNELLimitMinMax,
1401 fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ),
1402 fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
1403 fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
1405 fSliderY->Connect(
"PositionChanged()",
"TFitEditor",
this,
"DoSliderYMoved()");
1406 fSliderYMax->Connect(
"ValueSet(Long_t)",
"TFitEditor",
this,
"DoNumericSliderYChanged()");
1407 fSliderYMin->Connect(
"ValueSet(Long_t)",
"TFitEditor",
this,
"DoNumericSliderYChanged()");
1412 fSliderZ->Disconnect(
"PositionChanged()");
1414 if (!fSliderZParent->IsMapped())
1415 fSliderZParent->MapWindow();
1417 Int_t izmin = 0, izmax = 0, izrange = 0;
1421 izrange = fZaxis->GetNbins();
1422 izmin = fZaxis->GetFirst();
1423 izmax = fZaxis->GetLast();
1427 case kObjectGraph2D:
1428 case kObjectMultiGraph:
1435 if (izmin > 1 || izmax < izrange) {
1436 fSliderZ->SetRange(izmin,izmax);
1437 fSliderZ->SetPosition(izmin, izmax);
1439 fSliderZ->SetRange(1,izrange);
1440 fSliderZ->SetPosition(izmin,izmax);
1443 fSliderZ->SetScale(5);
1444 fSliderZ->Connect(
"PositionChanged()",
"TFitEditor",
this,
"DoSliderZMoved()");
1453 void TFitEditor::SetFitObject(TVirtualPad *pad, TObject *obj, Int_t event)
1455 if (event != kButton1Down)
return;
1463 if (!SetObjectType(obj))
return;
1467 ShowObjectName(obj);
1472 TF1* fitFunc = HasFitFunction();
1477 GetParameters(fFuncPars, fitFunc);
1479 TString tmpStr = fitFunc->GetExpFormula();
1482 if ( tmpStr.Length() == 0 )
1485 fEnteredFunc->SetText(fitFunc->GetName());
1486 en= fFuncList->FindEntry(fitFunc->GetName());
1488 SetEditable(kFALSE);
1494 fEnteredFunc->SetText(fitFunc->GetExpFormula().Data());
1495 en= fFuncList->FindEntry(fitFunc->GetExpFormula().Data());
1499 if (en) fFuncList->Select(en->EntryId());
1504 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
1506 if (te && fNone->GetState() == kButtonDown)
1507 fEnteredFunc->SetText(te->GetTitle());
1508 else if (te && fAdd->GetState() == kButtonDown)
1510 TString tmpStr = fEnteredFunc->GetText();
1512 tmpStr += te->GetTitle();
1513 fEnteredFunc->SetText(tmpStr);
1515 else if (te && fNormAdd->GetState() == kButtonDown)
1517 TString tmpStr = fEnteredFunc->GetText();
1519 tmpStr += te -> GetTitle();
1520 fEnteredFunc -> SetText(tmpStr);
1522 else if (te && fConv->GetState() == kButtonDown)
1524 TString tmpStr = fEnteredFunc->GetText();
1526 tmpStr +=te->GetTitle();
1527 fEnteredFunc->SetText(tmpStr);
1533 fEnteredFunc->SetText(
" ");
1535 fEnteredFunc->SelectAll();
1539 if (fSetParam->GetState() == kButtonDisabled)
1540 fSetParam->SetEnabled(kTRUE);
1541 if (fFitButton->GetState() == kButtonDisabled)
1542 fFitButton->SetEnabled(kTRUE);
1543 if (fResetButton->GetState() == kButtonDisabled)
1544 fResetButton->SetEnabled(kTRUE);
1552 void TFitEditor::DoNoSelection()
1554 if (gROOT->GetListOfCanvases()->IsEmpty()) {
1563 fStatusBar->SetText(
"No selection",0);
1564 fDataSet->Select(kFP_NOSEL, kFALSE);
1567 fSetParam->SetEnabled(kFALSE);
1568 fFitButton->SetEnabled(kFALSE);
1569 fResetButton->SetEnabled(kFALSE);
1570 fDrawAdvanced->SetState(kButtonDisabled);
1576 void TFitEditor::RecursiveRemove(TObject* obj)
1578 if (obj == fFitObject) {
1581 fStatusBar->SetText(
"No selection",0);
1582 fDataSet->Select(kFP_NOSEL, kFALSE);
1585 fFitButton->SetEnabled(kFALSE);
1586 fResetButton->SetEnabled(kFALSE);
1587 fSetParam->SetEnabled(kFALSE);
1589 TQObject::Connect(
"TCanvas",
"Selected(TVirtualPad *, TObject *, Int_t)",
1591 "SetFitObject(TVirtualPad *, TObject *, Int_t)");
1592 TQObject::Connect(
"TCanvas",
"Closed()",
"TFitEditor",
this,
1598 if (obj == fParentPad) {
1602 fStatusBar->SetText(
"No selection",0);
1603 fDataSet->Select(kFP_NOSEL, kFALSE);
1606 fFitButton->SetEnabled(kFALSE);
1607 fResetButton->SetEnabled(kFALSE);
1608 fSetParam->SetEnabled(kFALSE);
1616 void TFitEditor::FillFunctionList(Int_t)
1618 fFuncList->RemoveAll();
1620 if ( fTypeFit->GetSelected() == kFP_PRED1D && fDim <= 1 ) {
1622 fFuncList->AddEntry(
"gaus" , kFP_GAUS);
1623 fFuncList->AddEntry(
"gausn", kFP_GAUSN);
1624 fFuncList->AddEntry(
"expo", kFP_EXPO);
1625 fFuncList->AddEntry(
"landau", kFP_LAND);
1626 fFuncList->AddEntry(
"landaun",kFP_LANDN);
1627 fFuncList->AddEntry(
"pol0", kFP_POL0);
1628 fFuncList->AddEntry(
"pol1", kFP_POL1);
1629 fFuncList->AddEntry(
"pol2", kFP_POL2);
1630 fFuncList->AddEntry(
"pol3", kFP_POL3);
1631 fFuncList->AddEntry(
"pol4", kFP_POL4);
1632 fFuncList->AddEntry(
"pol5", kFP_POL5);
1633 fFuncList->AddEntry(
"pol6", kFP_POL6);
1634 fFuncList->AddEntry(
"pol7", kFP_POL7);
1635 fFuncList->AddEntry(
"pol8", kFP_POL8);
1636 fFuncList->AddEntry(
"pol9", kFP_POL9);
1637 fFuncList->AddEntry(
"cheb0", kFP_CHEB0);
1638 fFuncList->AddEntry(
"cheb1", kFP_CHEB1);
1639 fFuncList->AddEntry(
"cheb2", kFP_CHEB2);
1640 fFuncList->AddEntry(
"cheb3", kFP_CHEB3);
1641 fFuncList->AddEntry(
"cheb4", kFP_CHEB4);
1642 fFuncList->AddEntry(
"cheb5", kFP_CHEB5);
1643 fFuncList->AddEntry(
"cheb6", kFP_CHEB6);
1644 fFuncList->AddEntry(
"cheb7", kFP_CHEB7);
1645 fFuncList->AddEntry(
"cheb8", kFP_CHEB8);
1646 fFuncList->AddEntry(
"cheb9", kFP_CHEB9);
1647 fFuncList->AddEntry(
"user", kFP_USER);
1651 TGListBox *lb = fFuncList->GetListBox();
1652 lb->Resize(lb->GetWidth(), 200);
1655 fFuncList->Select(kFP_GAUS);
1659 else if ( fTypeFit->GetSelected() == kFP_PRED2D && fDim == 2 ) {
1660 fFuncList->AddEntry(
"xygaus", kFP_XYGAUS);
1661 fFuncList->AddEntry(
"bigaus", kFP_BIGAUS);
1662 fFuncList->AddEntry(
"xyexpo", kFP_XYEXP);
1663 fFuncList->AddEntry(
"xylandau", kFP_XYLAN);
1664 fFuncList->AddEntry(
"xylandaun", kFP_XYLANN);
1668 TGListBox *lb = fFuncList->GetListBox();
1669 lb->Resize(lb->GetWidth(), 200);
1672 fFuncList->Select(kFP_XYGAUS);
1677 else if ( fTypeFit->GetSelected() == kFP_UFUNC ) {
1678 Int_t newid = kFP_ALTFUNC;
1681 for (
auto f : fSystemFuncs) {
1685 if ( strncmp(f->GetName(),
"PrevFit", 7) != 0 ) {
1692 if ( f->GetNdim() == fDim || fDim == 0) {
1693 fFuncList->AddEntry(f->GetName(), newid++);
1699 if ( newid != kFP_ALTFUNC )
1700 fFuncList->Select(newid-1);
1701 else if( fDim == 1 ) {
1703 fTypeFit->Select(kFP_PRED1D, kTRUE);
1704 }
else if( fDim == 2 ) {
1706 fTypeFit->Select(kFP_PRED2D, kTRUE);
1710 else if ( fTypeFit->GetSelected() == kFP_PREVFIT ) {
1711 Int_t newid = kFP_ALTFUNC;
1714 std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(fFitObject);
1716 for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
1717 fFuncList->AddEntry(it->second->GetName(), newid++);
1721 if ( newid == kFP_ALTFUNC ) {
1723 fTypeFit->RemoveEntry(kFP_PREVFIT);
1726 fTypeFit->Select(kFP_PRED1D, kTRUE);
1727 else if ( fDim == 2 )
1729 fTypeFit->Select(kFP_PRED2D, kTRUE);
1732 fTypeFit->Select(kFP_UFUNC, kTRUE);
1737 fFuncList->Select(newid-1, kTRUE);
1745 void TFitEditor::FillMinMethodList(Int_t)
1747 fMinMethodList->RemoveAll();
1749 if ( fLibMinuit->GetState() == kButtonDown )
1751 fMinMethodList->AddEntry(
"MIGRAD" , kFP_MIGRAD);
1752 fMinMethodList->AddEntry(
"SIMPLEX" , kFP_SIMPLX);
1753 fMinMethodList->AddEntry(
"SCAN" , kFP_SCAN);
1754 fMinMethodList->AddEntry(
"Combination" , kFP_COMBINATION);
1755 fMinMethodList->Select(kFP_MIGRAD, kFALSE);
1756 fStatusBar->SetText(
"MIGRAD",2);
1757 }
else if ( fLibFumili->GetState() == kButtonDown )
1759 fMinMethodList->AddEntry(
"FUMILI" , kFP_FUMILI);
1760 fMinMethodList->Select(kFP_FUMILI, kFALSE);
1761 fStatusBar->SetText(
"FUMILI",2);
1762 }
else if ( fLibGSL->GetState() == kButtonDown )
1764 fMinMethodList->AddEntry(
"Fletcher-Reeves conjugate gradient" , kFP_GSLFR);
1765 fMinMethodList->AddEntry(
"Polak-Ribiere conjugate gradient" , kFP_GSLPR);
1766 fMinMethodList->AddEntry(
"BFGS conjugate gradient" , kFP_BFGS);
1767 fMinMethodList->AddEntry(
"BFGS conjugate gradient (Version 2)", kFP_BFGS2);
1768 fMinMethodList->AddEntry(
"Levenberg-Marquardt" , kFP_GSLLM);
1769 fMinMethodList->AddEntry(
"Simulated Annealing" , kFP_GSLSA);
1770 fMinMethodList->Select(kFP_GSLFR, kFALSE);
1771 fStatusBar->SetText(
"CONJFR",2);
1772 }
else if ( fLibGenetics->GetState() == kButtonDown )
1774 if ( gPluginMgr->FindHandler(
"ROOT::Math::Minimizer",
"GAlibMin") ) {
1775 fMinMethodList->AddEntry(
"GA Lib Genetic Algorithm" , kFP_GALIB);
1776 fMinMethodList->Select(kFP_GALIB, kFALSE);
1777 }
else if (gPluginMgr->FindHandler(
"ROOT::Math::Minimizer",
"Genetic")) {
1778 fMinMethodList->AddEntry(
"TMVA Genetic Algorithm" , kFP_TMVAGA);
1779 fMinMethodList->Select(kFP_TMVAGA, kFALSE);
1783 fMinMethodList->AddEntry(
"MIGRAD" , kFP_MIGRAD);
1784 fMinMethodList->AddEntry(
"SIMPLEX" , kFP_SIMPLX);
1785 fMinMethodList->AddEntry(
"FUMILI" , kFP_FUMILI);
1786 fMinMethodList->AddEntry(
"SCAN" , kFP_SCAN);
1787 fMinMethodList->AddEntry(
"Combination" , kFP_COMBINATION);
1788 fMinMethodList->Select(kFP_MIGRAD, kFALSE);
1789 fStatusBar->SetText(
"MIGRAD",2);
1793 void SearchCanvases(TSeqCollection* canvases, std::vector<TObject*>& objects)
1798 TIter canvasIter(canvases);
1800 while(TObject* obj = (TObject*) canvasIter()) {
1803 if ( TPad* can = dynamic_cast<TPad*>(obj))
1804 SearchCanvases(can->GetListOfPrimitives(), objects);
1806 else if ( dynamic_cast<TH1*>(obj)
1807 ||
dynamic_cast<TGraph*
>(obj)
1808 || dynamic_cast<TGraph2D*>(obj)
1809 ||
dynamic_cast<TMultiGraph*
>(obj)
1810 || dynamic_cast<THStack*>(obj)
1811 ||
dynamic_cast<TTree*
>(obj) ) {
1812 bool insertNew =
true;
1814 for ( std::vector<TObject*>::iterator i = objects.begin(); i != objects.end(); ++i )
1815 if ( (*i) == obj ) {
1821 if ( insertNew ) objects.push_back(obj);
1829 void TFitEditor::FillDataSetList()
1833 TGTextLBEntry * entry = (TGTextLBEntry*) fDataSet->GetSelectedEntry();
1834 TString selEntryStr;
1836 selEntryStr = entry->GetTitle();
1840 fDataSet->RemoveAll();
1841 std::vector<TObject*> objects;
1845 TList * l = gDirectory->GetList();
1848 TObject* obj = NULL;
1849 while ( (obj = (TObject*) next()) ) {
1851 if ( dynamic_cast<TH1*>(obj) ||
1852 dynamic_cast<TGraph2D*>(obj) ||
1853 dynamic_cast<TTree*>(obj) ) {
1854 objects.push_back(obj);
1862 SearchCanvases(gROOT->GetListOfCanvases(), objects);
1865 int selected = kFP_NOSEL;
1867 Int_t newid = kFP_NOSEL;
1868 fDataSet->AddEntry(
"No Selection", newid++);
1869 for ( std::vector<TObject*>::iterator i = objects.begin(); i != objects.end(); ++i ) {
1872 TString name = (*i)->ClassName(); name.Append(
"::"); name.Append((*i)->GetName());
1874 if ( selEntryStr && name == selEntryStr )
1876 fDataSet->AddEntry(name, newid++);
1883 fDataSet->Select(selected);
1890 TGComboBox* TFitEditor::BuildMethodList(TGFrame* parent, Int_t
id)
1892 TGComboBox *c =
new TGComboBox(parent,
id);
1893 c->AddEntry(
"Chi-square", kFP_MCHIS);
1894 c->AddEntry(
"Binned Likelihood", kFP_MBINL);
1895 c->AddEntry(
"Unbinned Likelihood", kFP_MUBIN);
1897 c->Select(kFP_MCHIS);
1904 void TFitEditor::DoAdvancedOptions()
1906 new TAdvancedGraphicsDialog( fClient->GetRoot(), GetMainFrame());
1912 void TFitEditor::DoEmptyBinsAllWeights1()
1914 if (fEmptyBinsWghts1->GetState() == kButtonDown)
1915 if (fAllWeights1->GetState() == kButtonDown)
1916 fAllWeights1->SetState(kButtonUp, kTRUE);
1921 void TFitEditor::DoUseFuncRange()
1923 if ( fUseRange->GetState() == kButtonDown ) {
1924 if (fNone->GetState() == kButtonDown || fNone->GetState() == kButtonDisabled) {
1926 TF1* tmpTF1 = FindFunction();
1928 if (GetFitObjectListOfFunctions()) {
1929 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
1930 tmpTF1 = (TF1*) GetFitObjectListOfFunctions()->FindObject( te->GetTitle() );
1935 Double_t xmin, ymin, zmin, xmax, ymax, zmax;
1937 tmpTF1->GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
1939 if ( fType != kObjectTree ) {
1940 fSliderXMin->SetNumber( xmin );
1941 fSliderXMax->SetNumber( xmax );
1942 DoNumericSliderXChanged();
1944 fSliderYMin->SetNumber( ymin );
1945 fSliderYMax->SetNumber( ymax );
1946 DoNumericSliderYChanged();
1951 fUseRange->SetState(kButtonDown);
1958 void TFitEditor::DoAllWeights1()
1960 if (fAllWeights1->GetState() == kButtonDown)
1961 if (fEmptyBinsWghts1->GetState() == kButtonDown)
1962 fEmptyBinsWghts1->SetState(kButtonUp, kTRUE);
1968 void TFitEditor::DoClose()
1976 void TFitEditor::DoUpdate()
1978 GetFunctionsFromSystem();
1985 void TFitEditor::DoFit()
1987 if (!fFitObject)
return;
1994 if ( fNone->GetState() != kButtonDisabled && CheckFunctionString(fEnteredFunc->GetText()) )
1997 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
1998 "Error...",
"2) Verify the entered function string!",
1999 kMBIconStop,kMBOk, 0);
2005 fFitButton->SetState(kButtonEngaged);
2006 if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kWatch);
2007 gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
2009 TVirtualPad *save =
nullptr;
2011 fParentPad->Disconnect(
"RangeAxisChanged()");
2016 if (fParentPad->GetCanvas())
2017 fParentPad->GetCanvas()->SetCursor(kWatch);
2021 ROOT::Fit::DataRange drange;
2030 static TF1 *fitFunc =
nullptr;
2035 fitFunc = GetFitFunction();
2037 std::cout <<
"TFitEditor::DoFit - using function " << fitFunc->GetName() <<
" " << fitFunc << std::endl;
2040 Error(
"DoFit",
"This should have never happend, the fitfunc pointer is NULL! - Please Report" );
2045 SetParameters(fFuncPars, fitFunc);
2047 ROOT::Math::MinimizerOptions mopts;
2049 TString strDrawOpts;
2050 RetrieveOptions(fitOpts, strDrawOpts, mopts, fitFunc->GetNpar());
2054 case kObjectHisto: {
2056 TH1 *hist =
dynamic_cast<TH1*
>(fFitObject);
2058 ROOT::Fit::FitObject(hist, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2062 case kObjectGraph: {
2064 TGraph *gr =
dynamic_cast<TGraph*
>(fFitObject);
2066 FitObject(gr, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2069 case kObjectMultiGraph: {
2071 TMultiGraph *mg =
dynamic_cast<TMultiGraph*
>(fFitObject);
2073 FitObject(mg, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2077 case kObjectGraph2D: {
2079 TGraph2D *g2d =
dynamic_cast<TGraph2D*
>(fFitObject);
2081 FitObject(g2d, fitFunc, fitOpts, mopts, strDrawOpts, drange);
2085 case kObjectHStack: {
2099 GetTreeVarsAndCuts(fDataSet, variables, cuts);
2103 TTree *tree =
dynamic_cast<TTree*
>(fFitObject);
2104 if ( !tree )
return;
2109 tree->Draw(variables,cuts,
"goff");
2111 TTreePlayer * player = (TTreePlayer*) tree->GetPlayer();
2113 Error(
"DoFit",
"Player reference is NULL");
2117 TSelectorDraw * selector = (TSelectorDraw* ) player->GetSelector();
2119 Error(
"DoFit",
"Selector reference is NULL");
2124 unsigned int ndim = player->GetDimension();
2126 Error(
"DoFit",
"NDIM == 0");
2130 std::vector<double *> vlist;
2131 for (
unsigned int i = 0; i < ndim; ++i) {
2132 double * v = selector->GetVal(i);
2133 if (v != 0) vlist.push_back(v);
2135 std::cerr <<
"pointer for variable " << i <<
" is zero" << std::endl;
2137 if (vlist.size() != ndim) {
2138 Error(
"DoFit",
"Vector is not complete");
2143 Long64_t nrows = player->GetSelectedRows();
2145 Error(
"DoFit",
"NROWS == 0");
2149 ROOT::Fit::UnBinData * fitdata =
new ROOT::Fit::UnBinData(nrows, ndim, vlist.begin());
2151 for (
int i = 0; i < std::min(
int(fitdata->Size()),10); ++i) {
2153 for (
unsigned int j = 0; j < ndim; ++j) {
2154 printf(
" x_%d [%d] = %f \n", j, i,*(fitdata->Coords(i)+j) );
2161 Foption_t fitOption;
2162 ROOT::Math::MinimizerOptions minOption;
2163 fitOption.Verbose=1;
2166 ROOT::Fit::UnBinFit(fitdata, fitFunc, fitOption, minOption);
2175 if (fDrawSame->GetState() == kButtonDown && fitFunc)
2176 fitFunc->Draw(
"same");
2181 GetParameters(fFuncPars,fitFunc);
2184 TF1* tmpTF1 = copyTF1(fitFunc);
2185 TString name = TString::Format(
"PrevFit-%d", (
int) fPrevFit.size() + 1);
2186 if (!strstr(fitFunc->GetName(),
"PrevFit"))
2187 name.Append(TString::Format(
"-%s", fitFunc->GetName()));
2188 tmpTF1->SetName(name.Data());
2189 fPrevFit.emplace(fFitObject, tmpTF1);
2190 fSystemFuncs.emplace_back( copyTF1(tmpTF1) );
2192 float xmin = 0.f, xmax = 0.f, ymin = 0.f, ymax = 0.f, zmin = 0.f, zmax = 0.f;
2194 fParentPad->Modified();
2199 if ( fType != kObjectTree ) fSliderX->GetPosition(xmin, xmax);
2200 if ( fDim > 1 ) fSliderY->GetPosition(ymin, ymax);
2201 if ( fDim > 2 ) fSliderZ->GetPosition(zmin, zmax);
2202 fParentPad->Update();
2211 if ( fType != kObjectTree ) { fSliderX->SetPosition(xmin, xmax); DoSliderXMoved(); }
2212 if ( fType != kObjectTree && fDim > 1 ) { fSliderY->SetPosition(ymin, ymax); DoSliderYMoved(); }
2213 if ( fType != kObjectTree && fDim > 2 ) { fSliderZ->SetPosition(zmin, zmax); DoSliderZMoved(); }
2214 if (fParentPad->GetCanvas())
2215 fParentPad->GetCanvas()->SetCursor(kPointer);
2216 fParentPad->Connect(
"RangeAxisChanged()",
"TFitEditor",
this,
"UpdateGUI()");
2218 if (save) gPad = save;
2219 if (fSetParam->GetState() == kButtonDisabled &&
2220 fLinearFit->GetState() == kButtonUp)
2221 fSetParam->SetState(kButtonUp);
2225 if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kPointer);
2226 gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
2227 fFitButton->SetState(kButtonUp);
2229 if ( !fTypeFit->FindEntry(
"Prev. Fit") )
2230 fTypeFit->InsertEntry(
"Prev. Fit",kFP_PREVFIT, kFP_UFUNC);
2232 fDrawAdvanced->SetState(kButtonUp);
2238 Int_t TFitEditor::CheckFunctionString(
const char *fname)
2241 if ( fDim == 1 || fDim == 0 ) {
2242 TF1 form(
"tmpCheck", fname);
2244 rvalue = form.IsValid() ? 0 : -1;
2245 }
else if ( fDim == 2 ) {
2246 TF2 form(
"tmpCheck", fname);
2248 rvalue = form.IsValid() ? 0 : -1;
2249 }
else if ( fDim == 3 ) {
2250 TF3 form(
"tmpCheck", fname);
2252 rvalue = form.IsValid() ? 0 : -1;
2263 void TFitEditor::DoAddition(Bool_t on)
2265 static Bool_t first = kFALSE;
2266 TString s = fEnteredFunc->GetText();
2269 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+
"...":s);
2271 fEnteredFunc->SetText(s.Data());
2273 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2284 void TFitEditor::DoNormAddition(Bool_t on)
2300 if (on) Info(
"DoNormAddition",
"Normalized addition is selected");
2308 void TFitEditor::DoConvolution(Bool_t on)
2324 if (on) Info(
"DoConvolution",
"Convolution is selected");
2330 void TFitEditor::DoDataSet(Int_t selected)
2332 if ( selected == kFP_NOSEL ) {
2338 TGTextLBEntry* textEntry =
static_cast<TGTextLBEntry*
>(fDataSet->GetListBox()->GetEntry(selected));
2339 if (!textEntry)
return;
2340 TString textEntryStr = textEntry->GetText()->GetString();
2341 TString name = textEntry->GetText()->GetString()+textEntry->GetText()->First(
':')+2;
2342 TString className = textEntryStr(0,textEntry->GetText()->First(
':'));
2345 TObject* objSelected(0);
2346 if ( className ==
"TTree" ) {
2349 if ( name.First(
' ') == kNPOS )
2352 lookStr = name(0, name.First(
' '));
2354 objSelected = gROOT->FindObject(lookStr);
2358 objSelected = gROOT->FindObject(name);
2367 if ( objSelected->InheritsFrom(TTree::Class()) &&
2368 name.First(
' ') == kNPOS ) {
2369 char variables[256] = {0};
char cuts[256] = {0};
2370 strlcpy(variables,
"Sin input!", 256);
2371 new TTreeInput( fClient->GetRoot(), GetMainFrame(), variables, cuts );
2372 if ( strcmp ( variables,
"" ) == 0 ) {
2376 ProcessTreeInput(objSelected, selected, variables, cuts);
2380 TPad* currentPad = NULL;
2382 std::queue<TPad*> stPad;
2383 TIter padIter( gROOT->GetListOfCanvases() );
2384 while ( TObject* canvas = static_cast<TObject*>(padIter() ) ) {
2385 if ( dynamic_cast<TPad*>(canvas) )
2386 stPad.push(dynamic_cast<TPad*>(canvas));
2389 while ( !stPad.empty() && !found ) {
2390 currentPad = stPad.front();
2392 TIter elemIter( currentPad->GetListOfPrimitives() );
2393 while ( TObject* elem = static_cast<TObject*>(elemIter() ) ) {
2394 if ( elem == objSelected ) {
2397 }
else if ( dynamic_cast<TPad*>(elem) )
2398 stPad.push( dynamic_cast<TPad*>(elem) );
2403 SetFitObject( found ? currentPad :
nullptr, objSelected, kButton1Down);
2406 void TFitEditor::ProcessTreeInput(TObject* objSelected, Int_t selected, TString variables, TString cuts)
2409 TString entryName = (objSelected)->ClassName(); entryName.Append(
"::"); entryName.Append((objSelected)->GetName());
2410 entryName.Append(
" (\""); entryName.Append(variables); entryName.Append(
"\", \"");
2411 entryName.Append(cuts); entryName.Append(
"\")");
2412 Int_t newid = fDataSet->GetNumberOfEntries() + kFP_NOSEL;
2413 fDataSet->InsertEntry(entryName, newid, selected );
2414 fDataSet->Select(newid);
2420 void TFitEditor::DoFunction(Int_t selected)
2422 TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
2425 R__ASSERT( selected == te->EntryId());
2429 bool editable =
false;
2430 if (fNone -> GetState() == kButtonDown || fNone->GetState() == kButtonDisabled)
2434 TF1* tmpTF1 = FindFunction();
2437 if (GetFitObjectListOfFunctions())
2438 tmpTF1 = (TF1*) GetFitObjectListOfFunctions()->FindObject( te->GetTitle() );
2440 if ( tmpTF1 && strcmp(tmpTF1->GetExpFormula(),
"") )
2443 fEnteredFunc->SetText(tmpTF1->GetExpFormula());
2447 if ( selected <= kFP_USER )
2451 fEnteredFunc->SetText(te->GetTitle());
2454 SetEditable(editable);
2456 else if (fAdd -> GetState() == kButtonDown)
2461 if (!strcmp(fEnteredFunc->GetText(),
""))
2463 fEnteredFunc->SetText(te->GetTitle());
2467 s = fEnteredFunc->GetTitle();
2468 TFormula tmp(
"tmp", fEnteredFunc->GetText());
2472 s += TString::Format(
"+%s(%d)", te->GetTitle(), np);
2474 s += TString::Format(
"%s(%d)", te->GetTitle(), np);
2475 fEnteredFunc->SetText(s.Data());
2478 else if (fNormAdd->GetState() == kButtonDown)
2483 if (!strcmp(fEnteredFunc->GetText(),
""))
2485 fEnteredFunc->SetText(te->GetTitle());
2489 s = fEnteredFunc->GetTitle();
2490 TFormula tmp(
"tmp", fEnteredFunc->GetText());
2494 s += TString::Format(
"+%s", te->GetTitle());
2496 s += TString::Format(
"%s", te->GetTitle());
2497 fEnteredFunc->SetText(s.Data());
2501 else if (fConv->GetState() == kButtonDown)
2506 if (!strcmp(fEnteredFunc->GetText(),
""))
2507 fEnteredFunc->SetText(te->GetTitle());
2510 s = fEnteredFunc->GetTitle();
2511 TFormula tmp(
"tmp", fEnteredFunc->GetText());
2515 s += TString::Format(
"*%s", te->GetTitle());
2517 s += TString::Format(
"%s", te->GetTitle());
2518 fEnteredFunc->SetText(s.Data());
2526 TString tmpStr = fEnteredFunc->GetText();
2529 if (tmpStr.Contains(
"pol") || tmpStr.Contains(
"++")) {
2530 fLinearFit->SetState(kButtonDown, kTRUE);
2532 fLinearFit->SetState(kButtonUp, kTRUE);
2535 fEnteredFunc->SelectAll();
2536 fSelLabel->SetText(tmpStr.Sizeof()>30?tmpStr(0,30)+
"...":tmpStr);
2537 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2541 TF1* fitFunc = GetFitFunction();
2544 if ( fitFunc && (
unsigned int) fitFunc->GetNpar() != fFuncPars.size() )
2555 void TFitEditor::DoEnteredFunction()
2557 if (!strcmp(fEnteredFunc->GetText(),
""))
return;
2560 Int_t ok = CheckFunctionString(fEnteredFunc->GetText());
2563 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
2564 "Error...",
"3) Verify the entered function string!",
2565 kMBIconStop,kMBOk, 0);
2570 TString s = fEnteredFunc->GetText();
2571 fSelLabel->SetText(s.Sizeof()>30?s(0,30)+
"...":s);
2572 ((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
2578 void TFitEditor::DoLinearFit()
2580 if (fLinearFit->GetState() == kButtonDown) {
2582 fBestErrors->SetState(kButtonDisabled);
2583 fImproveResults->SetState(kButtonDisabled);
2584 fEnableRobust->SetState(kButtonUp);
2588 fBestErrors->SetState(kButtonUp);
2589 fImproveResults->SetState(kButtonUp);
2590 fEnableRobust->SetState(kButtonDisabled);
2591 fRobustValue->SetState(kFALSE);
2599 void TFitEditor::DoNoChi2()
2608 void TFitEditor::DoRobustFit()
2610 if (fEnableRobust->GetState() == kButtonDown)
2611 fRobustValue->SetState(kTRUE);
2613 fRobustValue->SetState(kFALSE);
2619 void TFitEditor::DoNoStoreDrawing()
2621 if (fNoDrawing->GetState() == kButtonUp)
2622 fNoDrawing->SetState(kButtonDown);
2628 void TFitEditor::DoPrintOpt(Bool_t on)
2632 TGButton *btn = (TGButton *) gTQSender;
2633 Int_t
id = btn->WidgetId();
2637 fOptDefault->SetState(kButtonDown);
2638 fOptVerbose->SetState(kButtonUp);
2639 fOptQuiet->SetState(kButtonUp);
2641 fStatusBar->SetText(
"Prn: DEF",4);
2645 fOptVerbose->SetState(kButtonDown);
2646 fOptDefault->SetState(kButtonUp);
2647 fOptQuiet->SetState(kButtonUp);
2649 fStatusBar->SetText(
"Prn: VER",4);
2653 fOptQuiet->SetState(kButtonDown);
2654 fOptDefault->SetState(kButtonUp);
2655 fOptVerbose->SetState(kButtonUp);
2657 fStatusBar->SetText(
"Prn: QT",4);
2666 void TFitEditor::DoReset()
2669 fParentPad->Modified();
2670 fParentPad->Update();
2672 fEnteredFunc->SetText(
"gaus");
2677 if (fLinearFit->GetState() == kButtonDown)
2678 fLinearFit->SetState(kButtonUp, kTRUE);
2679 if (fBestErrors->GetState() == kButtonDown)
2680 fBestErrors->SetState(kButtonUp, kFALSE);
2681 if (fUseRange->GetState() == kButtonDown)
2682 fUseRange->SetState(kButtonUp, kFALSE);
2683 if (fAllWeights1->GetState() == kButtonDown)
2684 fAllWeights1->SetState(kButtonUp, kFALSE);
2685 if (fEmptyBinsWghts1->GetState() == kButtonDown)
2686 fEmptyBinsWghts1->SetState(kButtonUp, kFALSE);
2687 if (fImproveResults->GetState() == kButtonDown)
2688 fImproveResults->SetState(kButtonUp, kFALSE);
2689 if (fAdd2FuncList->GetState() == kButtonDown)
2690 fAdd2FuncList->SetState(kButtonUp, kFALSE);
2691 if (fUseGradient->GetState() == kButtonDown)
2692 fUseGradient->SetState(kButtonUp, kFALSE);
2693 if (fEnableRobust->GetState() == kButtonDown)
2694 fEnableRobust->SetState(kButtonUp, kFALSE);
2697 if (fDrawSame->GetState() == kButtonDown)
2698 fDrawSame->SetState(kButtonUp, kFALSE);
2699 if (fNoDrawing->GetState() == kButtonDown)
2700 fNoDrawing->SetState(kButtonUp, kFALSE);
2701 if (fNoStoreDrawing->GetState() == kButtonDown)
2702 fNoStoreDrawing->SetState(kButtonUp, kFALSE);
2703 fNone->SetState(kButtonDown, kTRUE);
2704 fFuncList->Select(1, kTRUE);
2707 if (fLibMinuit->GetState() != kButtonDown)
2708 fLibMinuit->SetState(kButtonDown, kTRUE);
2709 FillMinMethodList();
2710 if (fOptDefault->GetState() != kButtonDown)
2711 fOptDefault->SetState(kButtonDown, kTRUE);
2712 if (fErrorScale->GetNumber() != ROOT::Math::MinimizerOptions::DefaultErrorDef()) {
2713 fErrorScale->SetNumber(ROOT::Math::MinimizerOptions::DefaultErrorDef());
2714 fErrorScale->ReturnPressed();
2716 if (fTolerance->GetNumber() != ROOT::Math::MinimizerOptions::DefaultTolerance()) {
2717 fTolerance->SetNumber(ROOT::Math::MinimizerOptions::DefaultTolerance());
2718 fTolerance->ReturnPressed();
2720 if (fIterations->GetNumber() != ROOT::Math::MinimizerOptions::DefaultMaxIterations()) {
2721 fIterations->SetIntNumber(ROOT::Math::MinimizerOptions::DefaultMaxIterations());
2722 fIterations->ReturnPressed();
2729 void TFitEditor::DoSetParameters()
2732 TF1* fitFunc = GetFitFunction();
2735 if (!fitFunc) { Error(
"DoSetParameters",
"NUll function");
return; }
2741 if (fFuncPars.size() == 0) {
2744 InitParameters( fitFunc, (TH1*)fFitObject) ;
2747 InitParameters( fitFunc, ((TGraph*)fFitObject));
2749 case kObjectMultiGraph:
2750 InitParameters( fitFunc, ((TMultiGraph*)fFitObject));
2752 case kObjectGraph2D:
2753 InitParameters( fitFunc, ((TGraph2D*)fFitObject));
2761 GetParameters(fFuncPars, fitFunc);
2765 SetParameters(fFuncPars, fitFunc);
2768 if ( fParentPad ) fParentPad->Disconnect(
"RangeAxisChanged()");
2771 new TFitParametersDialog(gClient->GetDefaultRoot(), GetMainFrame(),
2772 fitFunc, fParentPad, &ret);
2775 GetParameters(fFuncPars, fitFunc);
2779 if (ret) fChangedParams = kTRUE;
2782 if ( fParentPad ) fParentPad->Connect(
"RangeAxisChanged()",
"TFitEditor",
this,
"UpdateGUI()");
2784 if ( fNone->GetState() != kButtonDisabled ) {
2793 void TFitEditor::DoSliderXMoved()
2795 if ( !fFitObject )
return;
2797 fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ) );
2798 fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ) );
2800 fUseRange->SetState(kButtonUp);
2809 void TFitEditor::DrawSelection(
bool restore)
2811 static Int_t px1old, py1old, px2old, py2old;
2813 if ( !fParentPad )
return;
2816 px1old = fParentPad->XtoAbsPixel(fParentPad->GetUxmin());
2817 py1old = fParentPad->YtoAbsPixel(fParentPad->GetUymin());
2818 px2old = fParentPad->XtoAbsPixel(fParentPad->GetUxmax());
2819 py2old = fParentPad->YtoAbsPixel(fParentPad->GetUymax());
2823 Int_t px1,py1,px2,py2;
2825 TVirtualPad *save = 0;
2831 Double_t xright = 0;
2832 xleft = fXaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5));
2833 xright = fXaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5));
2838 ymin = fYaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5));
2839 ymax = fYaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5));
2843 ymin = gPad->GetUymin();
2844 ymax = gPad->GetUymax();
2847 px1 = gPad->XtoAbsPixel(xleft);
2848 py1 = gPad->YtoAbsPixel(ymin);
2849 px2 = gPad->XtoAbsPixel(xright);
2850 py2 = gPad->YtoAbsPixel(ymax);
2852 if (gPad->GetCanvas()) gPad->GetCanvas()->FeedbackMode(kTRUE);
2853 gPad->SetLineWidth(1);
2854 gPad->SetLineColor(2);
2856 gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
2857 gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
2864 if(save) gPad = save;
2870 void TFitEditor::DoNumericSliderXChanged()
2872 if ( fSliderXMin->GetNumber() > fSliderXMax->GetNumber() ) {
2874 fSliderX->GetPosition(xmin, xmax);
2875 fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( xmin ) ) );
2876 fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( xmax ) ) );
2880 fSliderX->SetPosition(fXaxis->FindBin( fSliderXMin->GetNumber() ),
2881 fXaxis->FindBin( fSliderXMax->GetNumber() ));
2883 fUseRange->SetState(kButtonUp);
2891 void TFitEditor::DoSliderYMoved()
2893 if ( !fFitObject )
return;
2895 fSliderYMin->SetNumber( fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ) );
2896 fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ) );
2898 fUseRange->SetState(kButtonUp);
2906 void TFitEditor::DoNumericSliderYChanged()
2908 if ( fSliderYMin->GetNumber() > fSliderYMax->GetNumber() ) {
2910 fSliderY->GetPosition(ymin, ymax);
2911 fSliderYMin->SetNumber( fYaxis->GetBinLowEdge( static_cast<Int_t>( ymin ) ) );
2912 fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( ymax ) ) );
2916 fSliderY->SetPosition( fYaxis->FindBin( fSliderYMin->GetNumber() ),
2917 fYaxis->FindBin( fSliderYMax->GetNumber() ));
2919 fUseRange->SetState(kButtonUp);
2927 void TFitEditor::DoSliderZMoved()
2934 void TFitEditor::DoUserDialog()
2936 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
2937 "Info",
"Dialog of user method is not implemented yet",
2938 kMBIconAsterisk,kMBOk, 0);
2944 void TFitEditor::SetFunction(
const char *
function)
2946 fEnteredFunc->SetText(
function);
2953 Bool_t TFitEditor::SetObjectType(TObject* obj)
2955 Bool_t set = kFALSE;
2959 if (obj->InheritsFrom(TGraph::Class())) {
2960 fType = kObjectGraph;
2963 fMethodList->RemoveAll();
2964 fMethodList->AddEntry(
"Chi-square", kFP_MCHIS);
2965 fMethodList->Select(kFP_MCHIS, kFALSE);
2966 fRobustValue->SetState(kTRUE);
2967 fRobustValue->GetNumberEntry()->SetToolTipText(
"Set robust value");
2968 }
else if (obj->InheritsFrom(TGraph2D::Class())) {
2969 fType = kObjectGraph2D;
2972 fMethodList->RemoveAll();
2973 fMethodList->AddEntry(
"Chi-square", kFP_MCHIS);
2974 fMethodList->Select(kFP_MCHIS, kFALSE);
2975 }
else if (obj->InheritsFrom(THStack::Class())) {
2976 fType = kObjectHStack;
2978 TH1 *hist = (TH1 *)((THStack *)obj)->GetHists()->First();
2979 fDim = hist->GetDimension();
2980 fMethodList->RemoveAll();
2981 fMethodList->AddEntry(
"Chi-square", kFP_MCHIS);
2982 fMethodList->Select(kFP_MCHIS, kFALSE);
2983 }
else if (obj->InheritsFrom(TTree::Class())) {
2984 fType = kObjectTree;
2986 TString variables, cuts;
2987 GetTreeVarsAndCuts(fDataSet, variables, cuts);
2989 for (
int i = 0; i < variables.Length() && fDim <= 2; ++i )
2990 if (
':' == variables[i] ) fDim += 1;
2994 if ( fDim > 2 ) fDim = 0;
2995 fMethodList->RemoveAll();
2996 fMethodList->AddEntry(
"Unbinned Likelihood", kFP_MUBIN);
2997 fMethodList->Select(kFP_MUBIN, kFALSE);
2998 }
else if (obj->InheritsFrom(TH1::Class())){
2999 fType = kObjectHisto;
3001 fDim = ((TH1*)obj)->GetDimension();
3002 fMethodList->RemoveAll();
3003 fMethodList->AddEntry(
"Chi-square", kFP_MCHIS);
3004 fMethodList->AddEntry(
"Binned Likelihood", kFP_MBINL);
3005 fMethodList->Select(kFP_MCHIS, kFALSE);
3006 }
else if (obj->InheritsFrom(TMultiGraph::Class())) {
3007 fType = kObjectMultiGraph;
3010 fMethodList->RemoveAll();
3011 fMethodList->AddEntry(
"Chi-square", kFP_MCHIS);
3012 fMethodList->Select(kFP_MCHIS, kFALSE);
3013 fRobustValue->SetState(kTRUE);
3014 fRobustValue->GetNumberEntry()->SetToolTipText(
"Set robust value");
3019 if ( fDim < 2 || fType == kObjectTree )
3020 fGeneral->HideFrame(fSliderYParent);
3022 fGeneral->ShowFrame(fSliderYParent);
3024 if ( fDim < 1 || fType == kObjectTree )
3025 fGeneral->HideFrame(fSliderXParent);
3027 fGeneral->ShowFrame(fSliderXParent);
3031 if ( !fTypeFit->FindEntry(
"Predef-1D") )
3032 fTypeFit->InsertEntry(
"Predef-1D", kFP_PRED1D, kFP_PREVFIT);
3034 if ( fTypeFit->FindEntry(
"Predef-1D") )
3035 fTypeFit->RemoveEntry(kFP_PRED1D);
3039 if ( !fTypeFit->FindEntry(
"Predef-2D") )
3040 fTypeFit->InsertEntry(
"Predef-2D", kFP_PRED2D, kFP_PREVFIT);
3042 if ( fTypeFit->FindEntry(
"Predef-2D") )
3043 fTypeFit->RemoveEntry(kFP_PRED2D);
3052 void TFitEditor::ShowObjectName(TObject* obj)
3055 bool isTree =
false;
3059 name = obj->ClassName();
3061 name.Append(obj->GetName());
3062 isTree = strcmp(obj->ClassName(),
"TTree") == 0;
3064 name =
"No object selected";
3066 fStatusBar->SetText(name.Data(),0);
3070 TGTextLBEntry* selectedEntry =
static_cast<TGTextLBEntry*
> ( fDataSet->GetSelectedEntry());
3071 if ( selectedEntry ) {
3072 TString selectedName = selectedEntry->GetText()->GetString();
3074 selectedName = selectedName(0, selectedName.First(
' '));
3075 if ( name.CompareTo(selectedName) == 0 ) {
3082 Int_t entryId = kFP_NOSEL+1;
3084 while ( TGTextLBEntry* entry = static_cast<TGTextLBEntry*>
3085 ( fDataSet->GetListBox()->GetEntry(entryId)) ) {
3086 TString compareName = entry->GetText()->GetString();
3088 compareName = compareName(0, compareName.First(
' '));
3089 if ( name.CompareTo(compareName) == 0 ) {
3091 fDataSet->Select(entryId,
false);
3100 fDataSet->AddEntry(name.Data(), entryId);
3101 fDataSet->Select(entryId, kTRUE);
3110 Option_t *TFitEditor::GetDrawOption()
const
3112 if (!fParentPad)
return "";
3114 TListIter next(fParentPad->GetListOfPrimitives());
3116 while ((obj = next())) {
3117 if (obj == fFitObject)
return next.GetOption();
3125 void TFitEditor::DoLibrary(Bool_t on)
3127 TGButton *bt = (TGButton *)gTQSender;
3128 Int_t
id = bt->WidgetId();
3137 fLibMinuit->SetState(kButtonDown);
3138 fLibMinuit2->SetState(kButtonUp);
3139 fLibFumili->SetState(kButtonUp);
3140 if ( fLibGSL->GetState() != kButtonDisabled )
3141 fLibGSL->SetState(kButtonUp);
3142 if ( fLibGenetics->GetState() != kButtonDisabled )
3143 fLibGenetics->SetState(kButtonUp);
3144 fStatusBar->SetText(
"LIB Minuit", 1);
3153 fLibMinuit->SetState(kButtonUp);
3154 fLibMinuit2->SetState(kButtonDown);
3155 fLibFumili->SetState(kButtonUp);
3156 if ( fLibGSL->GetState() != kButtonDisabled )
3157 fLibGSL->SetState(kButtonUp);
3158 if ( fLibGenetics->GetState() != kButtonDisabled )
3159 fLibGenetics->SetState(kButtonUp);
3160 fStatusBar->SetText(
"LIB Minuit2", 1);
3168 fLibMinuit->SetState(kButtonUp);
3169 fLibMinuit2->SetState(kButtonUp);
3170 fLibFumili->SetState(kButtonDown);
3171 if ( fLibGSL->GetState() != kButtonDisabled )
3172 fLibGSL->SetState(kButtonUp);
3173 if ( fLibGenetics->GetState() != kButtonDisabled )
3174 fLibGenetics->SetState(kButtonUp);
3175 fStatusBar->SetText(
"LIB Fumili", 1);
3182 fLibMinuit->SetState(kButtonUp);
3183 fLibMinuit2->SetState(kButtonUp);
3184 fLibFumili->SetState(kButtonUp);
3185 if ( fLibGSL->GetState() != kButtonDisabled )
3186 fLibGSL->SetState(kButtonDown);
3187 if ( fLibGenetics->GetState() != kButtonDisabled )
3188 fLibGenetics->SetState(kButtonUp);
3189 fStatusBar->SetText(
"LIB GSL", 1);
3196 fLibMinuit->SetState(kButtonUp);
3197 fLibMinuit2->SetState(kButtonUp);
3198 fLibFumili->SetState(kButtonUp);
3199 if ( fLibGSL->GetState() != kButtonDisabled )
3200 fLibGSL->SetState(kButtonUp);
3201 if ( fLibGenetics->GetState() != kButtonDisabled )
3202 fLibGenetics->SetState(kButtonDown);
3203 fStatusBar->SetText(
"LIB Genetics", 1);
3209 FillMinMethodList();
3215 void TFitEditor::DoMinMethod(Int_t )
3217 if ( fMinMethodList->GetSelected() == kFP_MIGRAD )
3218 fStatusBar->SetText(
"MIGRAD",2);
3219 else if ( fMinMethodList->GetSelected() == kFP_FUMILI)
3220 fStatusBar->SetText(
"FUMILI",2);
3221 else if ( fMinMethodList->GetSelected() == kFP_SIMPLX )
3222 fStatusBar->SetText(
"SIMPLEX",2);
3223 else if ( fMinMethodList->GetSelected() == kFP_SCAN )
3224 fStatusBar->SetText(
"SCAN",2);
3225 else if ( fMinMethodList->GetSelected() == kFP_COMBINATION )
3226 fStatusBar->SetText(
"Combination",2);
3227 else if ( fMinMethodList->GetSelected() == kFP_GSLFR )
3228 fStatusBar->SetText(
"CONJFR",2);
3229 else if ( fMinMethodList->GetSelected() == kFP_GSLPR )
3230 fStatusBar->SetText(
"CONJPR",2);
3231 else if ( fMinMethodList->GetSelected() == kFP_BFGS )
3232 fStatusBar->SetText(
"BFGS",2);
3233 else if ( fMinMethodList->GetSelected() == kFP_BFGS2 )
3234 fStatusBar->SetText(
"BFGS2",2);
3235 else if ( fMinMethodList->GetSelected() == kFP_GSLLM )
3236 fStatusBar->SetText(
"GSLLM",2);
3237 else if ( fMinMethodList->GetSelected() == kFP_GSLSA)
3238 fStatusBar->SetText(
"SimAn",2);
3239 else if ( fMinMethodList->GetSelected() == kFP_TMVAGA )
3240 fStatusBar->SetText(
"TMVAGA",2);
3241 else if ( fMinMethodList->GetSelected() == kFP_GALIB )
3242 fStatusBar->SetText(
"GALIB",2);
3250 void TFitEditor::DoMaxIterations()
3252 Long_t itr = fIterations->GetIntNumber();
3253 fStatusBar->SetText(Form(
"Itr: %ld",itr),2);
3259 void TFitEditor::MakeTitle(TGCompositeFrame *parent,
const char *title)
3261 TGCompositeFrame *ht =
new TGCompositeFrame(parent, 350, 10,
3262 kFixedWidth | kHorizontalFrame);
3263 ht->AddFrame(
new TGLabel(ht, title),
3264 new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
3265 ht->AddFrame(
new TGHorizontal3DLine(ht),
3266 new TGLayoutHints(kLHintsExpandX | kLHintsCenterY, 5, 5, 2, 2));
3267 parent->AddFrame(ht,
new TGLayoutHints(kLHintsTop, 5, 0, 5, 0));
3274 TF1* TFitEditor::HasFitFunction()
3277 TList *lf = GetFitObjectListOfFunctions();
3283 if ( !fTypeFit->FindEntry(
"Prev. Fit") )
3284 fTypeFit->InsertEntry(
"Prev. Fit",kFP_PREVFIT, kFP_UFUNC);
3288 TIter next(lf, kIterForward);
3290 while ((obj2 = next())) {
3291 if (obj2->InheritsFrom(TF1::Class())) {
3295 for ( it = fPrevFit.begin(); it != fPrevFit.end(); ++it) {
3297 if ( it->first != fFitObject )
continue;
3299 if ( strcmp( func->GetName(), it->second->GetName() ) == 0 )
3301 if ( strcmp( func->GetName(),
"PrevFitTMP" ) == 0 )
3307 if ( it == fPrevFit.end() ) {
3308 fPrevFit.emplace(fFitObject, copyTF1(func));
3314 fTypeFit->Select(kFP_PREVFIT);
3317 fDrawAdvanced->SetState(kButtonUp);
3322 fTypeFit->Select(kFP_UFUNC);
3329 fDrawAdvanced->SetState(kButtonDisabled);
3337 void TFitEditor::RetrieveOptions(Foption_t& fitOpts, TString& drawOpts, ROOT::Math::MinimizerOptions& minOpts, Int_t )
3341 fitOpts.Range = (fUseRange->GetState() == kButtonDown);
3342 fitOpts.Integral = (fIntegral->GetState() == kButtonDown);
3343 fitOpts.More = (fImproveResults->GetState() == kButtonDown);
3344 fitOpts.Errors = (fBestErrors->GetState() == kButtonDown);
3345 fitOpts.Like = (fMethodList->GetSelected() != kFP_MCHIS);
3347 if (fEmptyBinsWghts1->GetState() == kButtonDown)
3349 else if (fAllWeights1->GetState() == kButtonDown)
3352 TString tmpStr = fEnteredFunc->GetText();
3353 if ( !(fLinearFit->GetState() == kButtonDown) &&
3354 (tmpStr.Contains(
"pol") || tmpStr.Contains(
"++")) )
3366 if (fChangedParams) {
3369 fChangedParams = kFALSE;
3373 fitOpts.Nostore = (fNoStoreDrawing->GetState() == kButtonDown);
3374 fitOpts.Nograph = (fNoDrawing->GetState() == kButtonDown);
3375 fitOpts.Plus = (fAdd2FuncList->GetState() == kButtonDown);
3376 fitOpts.Gradient = (fUseGradient->GetState() == kButtonDown);
3377 fitOpts.Quiet = ( fOptQuiet->GetState() == kButtonDown );
3378 fitOpts.Verbose = ( fOptVerbose->GetState() == kButtonDown );
3380 if ( !(fType != kObjectGraph) && (fEnableRobust->GetState() == kButtonDown) )
3383 fitOpts.hRobust = fRobustValue->GetNumber();
3386 drawOpts = GetDrawOption();
3388 if ( fLibMinuit->GetState() == kButtonDown )
3389 minOpts.SetMinimizerType (
"Minuit");
3390 else if ( fLibMinuit2->GetState() == kButtonDown)
3391 minOpts.SetMinimizerType (
"Minuit2" );
3392 else if ( fLibFumili->GetState() == kButtonDown )
3393 minOpts.SetMinimizerType (
"Fumili" );
3394 else if ( fLibGSL->GetState() == kButtonDown )
3395 minOpts.SetMinimizerType (
"GSLMultiMin" );
3397 if ( fMinMethodList->GetSelected() == kFP_MIGRAD )
3398 minOpts.SetMinimizerAlgorithm(
"Migrad" );
3399 else if ( fMinMethodList->GetSelected() == kFP_FUMILI)
3400 if ( fLibMinuit2->GetState() == kButtonDown )
3401 minOpts.SetMinimizerAlgorithm(
"Fumili2" );
3403 minOpts.SetMinimizerAlgorithm(
"Fumili" );
3404 else if ( fMinMethodList->GetSelected() == kFP_SIMPLX )
3405 minOpts.SetMinimizerAlgorithm(
"Simplex" );
3406 else if ( fMinMethodList->GetSelected() == kFP_SCAN )
3407 minOpts.SetMinimizerAlgorithm(
"Scan" );
3408 else if ( fMinMethodList->GetSelected() == kFP_COMBINATION )
3409 minOpts.SetMinimizerAlgorithm(
"Minimize" );
3410 else if ( fMinMethodList->GetSelected() == kFP_GSLFR )
3411 minOpts.SetMinimizerAlgorithm(
"conjugatefr" );
3412 else if ( fMinMethodList->GetSelected() == kFP_GSLPR )
3413 minOpts.SetMinimizerAlgorithm(
"conjugatepr" );
3414 else if ( fMinMethodList->GetSelected() == kFP_BFGS )
3415 minOpts.SetMinimizerAlgorithm(
"bfgs" );
3416 else if ( fMinMethodList->GetSelected() == kFP_BFGS2 )
3417 minOpts.SetMinimizerAlgorithm(
"bfgs2" );
3418 else if ( fMinMethodList->GetSelected() == kFP_GSLLM ) {
3419 minOpts.SetMinimizerType (
"GSLMultiFit" );
3420 minOpts.SetMinimizerAlgorithm(
"" );
3421 }
else if ( fMinMethodList->GetSelected() == kFP_GSLSA) {
3422 minOpts.SetMinimizerType (
"GSLSimAn" );
3423 minOpts.SetMinimizerAlgorithm(
"" );
3424 }
else if ( fMinMethodList->GetSelected() == kFP_TMVAGA) {
3425 minOpts.SetMinimizerType (
"Geneti2c" );
3426 minOpts.SetMinimizerAlgorithm(
"" );
3427 }
else if ( fMinMethodList->GetSelected() == kFP_GALIB) {
3428 minOpts.SetMinimizerType (
"GAlibMin" );
3429 minOpts.SetMinimizerAlgorithm(
"" );
3432 minOpts.SetErrorDef ( fErrorScale->GetNumber() );
3433 minOpts.SetTolerance( fTolerance->GetNumber() );
3434 minOpts.SetMaxIterations(fIterations->GetIntNumber());
3435 minOpts.SetMaxFunctionCalls(fIterations->GetIntNumber());
3438 void TFitEditor::SetEditable(Bool_t state)
3444 fEnteredFunc-> SetState(kTRUE);
3445 fAdd -> SetState(kButtonUp, kFALSE);
3446 fNormAdd -> SetState(kButtonUp, kFALSE);
3447 fConv -> SetState(kButtonUp, kFALSE);
3448 fNone -> SetState(kButtonDown,kFALSE);
3452 fEnteredFunc-> SetState(kFALSE);
3453 fAdd -> SetState(kButtonDisabled, kFALSE);
3454 fNormAdd -> SetState(kButtonDisabled, kFALSE);
3455 fConv -> SetState(kButtonDisabled, kFALSE);
3456 fNone -> SetState(kButtonDisabled, kFALSE);
3460 void TFitEditor::GetRanges(ROOT::Fit::DataRange& drange)
3465 if ( fType == kObjectTree )
return;
3467 if ( fType != kObjectTree ) {
3468 Int_t ixmin = (Int_t)(fSliderX->GetMinPosition());
3469 Int_t ixmax = (Int_t)(fSliderX->GetMaxPosition());
3470 Double_t xmin = fXaxis->GetBinLowEdge(ixmin);
3471 Double_t xmax = fXaxis->GetBinUpEdge(ixmax);
3472 drange.AddRange(0,xmin, xmax);
3477 Int_t iymin = (Int_t)(fSliderY->GetMinPosition());
3478 Int_t iymax = (Int_t)(fSliderY->GetMaxPosition());
3479 Double_t ymin = fYaxis->GetBinLowEdge(iymin);
3480 Double_t ymax = fYaxis->GetBinUpEdge(iymax);
3481 drange.AddRange(1,ymin, ymax);
3485 Int_t izmin = (Int_t)(fSliderZ->GetMinPosition());
3486 Int_t izmax = (Int_t)(fSliderZ->GetMaxPosition());
3487 Double_t zmin = fZaxis->GetBinLowEdge(izmin);
3488 Double_t zmax = fZaxis->GetBinUpEdge(izmax);
3489 drange.AddRange(2,zmin, zmax);
3493 TList* TFitEditor::GetFitObjectListOfFunctions()
3497 TList *listOfFunctions = 0;
3502 listOfFunctions = ((TH1 *)fFitObject)->GetListOfFunctions();
3506 listOfFunctions = ((TGraph *)fFitObject)->GetListOfFunctions();
3509 case kObjectMultiGraph:
3510 listOfFunctions = ((TMultiGraph *)fFitObject)->GetListOfFunctions();
3513 case kObjectGraph2D:
3514 listOfFunctions = ((TGraph2D *)fFitObject)->GetListOfFunctions();
3523 return listOfFunctions;
3526 void TFitEditor::GetFunctionsFromSystem()
3532 for (
auto func : fSystemFuncs)
3535 fSystemFuncs.clear();
3539 const unsigned int nfuncs = 16;
3540 const char* fnames[nfuncs] = {
"gaus" ,
"gausn",
"expo",
"landau",
3541 "landaun",
"pol0",
"pol1",
"pol2",
3542 "pol3",
"pol4",
"pol5",
"pol6",
3543 "pol7",
"pol8",
"pol9",
"user"
3547 TIter functionsIter(gROOT->GetListOfFunctions());
3549 while( ( obj = (TObject*) functionsIter() ) ) {
3551 if ( TF1* func = dynamic_cast<TF1*>(obj) ) {
3552 bool addFunction =
true;
3554 for (
unsigned int i = 0; i < nfuncs; ++i ) {
3555 if ( strcmp( func->GetName(), fnames[i] ) == 0 ) {
3556 addFunction =
false;
3562 fSystemFuncs.emplace_back( copyTF1(func) );
3567 TList* TFitEditor::GetListOfFittingFunctions(TObject* obj)
3577 if (!obj) obj = fFitObject;
3579 TList *retList =
new TList();
3581 std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(obj);
3582 for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
3583 retList->Add(it->second);
3589 TF1* TFitEditor::GetFitFunction()
3596 if ( fNone->GetState() == kButtonDisabled )
3599 TF1* tmpF1 = FindFunction();
3603 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
3604 "Error...",
"1) Verify the entered function string!",
3605 kMBIconStop,kMBOk, 0);
3611 fitFunc = (TF1*)tmpF1->IsA()->New();
3612 tmpF1->Copy(*fitFunc);
3619 if (
int(fFuncPars.size()) != tmpF1->GetNpar() )
3621 fitFunc->SetParameters(tmpF1->GetParameters());
3622 GetParameters(fFuncPars, fitFunc);
3624 SetParameters(fFuncPars, fitFunc);
3632 ROOT::Fit::DataRange drange;
3634 double xmin, xmax, ymin, ymax, zmin, zmax;
3635 drange.GetRange(xmin, xmax, ymin, ymax, zmin, zmax);
3640 if ( fDim == 1 || fDim == 0 )
3643 fitFunc =
new TF1(
"PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax );
3645 if (fNormAdd->IsOn())
3647 if (fSumFunc)
delete fSumFunc;
3648 fSumFunc =
new TF1NormSum(fEnteredFunc->GetText(), xmin, xmax);
3649 fitFunc =
new TF1(
"PrevFitTMP", *fSumFunc, xmin, xmax, fSumFunc->GetNpar());
3650 for (
int i = 0; i < fitFunc->GetNpar(); ++i) fitFunc->SetParName(i, fSumFunc->GetParName(i) );
3654 if (fConv -> IsOn())
3656 if (fConvFunc)
delete fConvFunc;
3657 fConvFunc =
new TF1Convolution(fEnteredFunc->GetText());
3658 fitFunc =
new TF1(
"PrevFitTMP", *fConvFunc, xmin, xmax, fConvFunc->GetNpar());
3659 for (
int i = 0; i < fitFunc->GetNpar(); ++i) fitFunc->SetParName(i, fConvFunc->GetParName(i) );
3663 else if ( fDim == 2 ) {
3664 fitFunc =
new TF2(
"PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax, ymin, ymax );
3666 else if ( fDim == 3 ) {
3667 fitFunc =
new TF3(
"PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax, ymin, ymax, zmin, zmax );
3671 if ( fNone->GetState() != kButtonDisabled )
3674 TF1* tmpF1 = FindFunction();
3679 if ( tmpF1 != 0 && fitFunc != 0 &&
3680 strcmp(tmpF1->GetExpFormula(), fEnteredFunc->GetText()) == 0 ) {
3684 tmpF1->Copy(*fitFunc);
3685 if (
int(fFuncPars.size()) != tmpF1->GetNpar() )
3687 GetParameters(fFuncPars, fitFunc);