/*
<img src="gif/TFitEditor.gif">
*/
//End_Html
#include "TFitEditor.h"
#include "TROOT.h"
#include "TClass.h"
#include "TCanvas.h"
#include "TGTab.h"
#include "TGLabel.h"
#include "TG3DLine.h"
#include "TGComboBox.h"
#include "TGTextEntry.h"
#include "TGFont.h"
#include "TGGC.h"
#include "TGButtonGroup.h"
#include "TGNumberEntry.h"
#include "TGDoubleSlider.h"
#include "TGStatusBar.h"
#include "TFitParametersDialog.h"
#include "TGMsgBox.h"
#include "TAxis.h"
#include "TGraph.h"
#include "TGraph2D.h"
#include "TH1.h"
#include "TH2.h"
#include "HFitInterface.h"
#include "TF1.h"
#include "TF2.h"
#include "TF3.h"
#include "TTimer.h"
#include "THStack.h"
#include "TMath.h"
#include "Fit/UnBinData.h"
#include "Fit/BinData.h"
#include "Fit/BinData.h"
#include "TMultiGraph.h"
#include "TTree.h"
#include "TTreePlayer.h"
#include "TTreeInput.h"
#include "TAdvancedGraphicsDialog.h"
#include "RConfigure.h"
#include "TPluginManager.h"
#include <sstream>
#include <vector>
#include <queue>
using std::vector;
using std::queue;
using std::pair;
using std::ostringstream;
using std::make_pair;
#include "CommonDefs.h"
void SearchCanvases(TSeqCollection* canvases, std::vector<TObject*>& objects);
typedef std::multimap<TObject*, TF1*> FitFuncMap_t;
TF1* TFitEditor::FindFunction()
{
std::vector<TF1*>& funcList(fSystemFuncs);
TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
if ( !te ) return 0;
TString name(te->GetTitle());
if ( fTypeFit->GetSelected() == kFP_UFUNC ) {
for ( fSystemFuncIter it = funcList.begin();
it != funcList.end(); ++it ) {
TF1* f = (*it);
if ( strcmp( f->GetName(), name ) == 0 )
return f;
}
} else if ( fTypeFit->GetSelected() == kFP_PREVFIT ) {
std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(fFitObject);
for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
TF1* f = it->second;
if ( strcmp( f->GetName(), name ) == 0 )
return f;
}
}
return 0;
}
TF1* copyTF1(TF1* f)
{
double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
if ( dynamic_cast<TF3*>(f) != 0 ) {
TF3* fnew = (TF3*)f->IsA()->New();
f->Copy(*fnew);
f->GetRange(xmin,ymin,zmin,xmax,ymax,zmax);
fnew->SetRange(xmin,ymin,zmin,xmax,ymax,zmax);
fnew->SetParent( 0 );
fnew->SetBit(TFormula::kNotGlobal);
return fnew;
} else if ( dynamic_cast<TF2*>(f) != 0 ) {
TF2* fnew = (TF2*)f->IsA()->New();
f->Copy(*fnew);
f->GetRange(xmin,ymin,xmax,ymax);
fnew->SetRange(xmin,ymin,xmax,ymax);
fnew->Save(xmin,xmax,ymin,ymax,0,0);
fnew->SetParent( 0 );
fnew->SetBit(TFormula::kNotGlobal);
return fnew;
} else {
TF1* fnew = (TF1*)f->IsA()->New();
f->Copy(*fnew);
f->GetRange(xmin,xmax);
fnew->SetRange(xmin,xmax);
if ( '\0' != fnew->GetExpFormula()[0] )
fnew->Save(xmin,xmax,0,0,0,0);
fnew->SetParent( 0 );
fnew->SetBit(TFormula::kNotGlobal);
return fnew;
}
}
void GetParameters(TFitEditor::FuncParams_t & pars, TF1* func)
{
int npar = func->GetNpar();
if (npar != (int) pars.size() ) pars.resize(npar);
for ( Int_t i = 0; i < npar; ++i )
{
Double_t par_min, par_max;
pars[i][PAR_VAL] = func->GetParameter(i);
func->GetParLimits(i, par_min, par_max);
pars[i][PAR_MIN] = par_min;
pars[i][PAR_MAX] = par_max;
}
}
void SetParameters(TFitEditor::FuncParams_t & pars, TF1* func)
{
int npar = func->GetNpar();
if (npar > (int) pars.size() ) pars.resize(npar);
for ( Int_t i = 0; i < npar; ++i )
{
func->SetParameter(i, pars[i][PAR_VAL]);
func->SetParLimits(i, pars[i][PAR_MIN], pars[i][PAR_MAX]);
}
}
template<class FitObject>
void InitParameters(TF1* func, FitObject * fitobj)
{
const int special = func->GetNumber();
if (100 == special || 400 == special) {
ROOT::Fit::BinData data;
ROOT::Fit::FillData(data,fitobj,func);
ROOT::Fit::InitGaus(data, func);
} else if ( 110 == special || 410 == special ) {
ROOT::Fit::BinData data;
ROOT::Fit::FillData(data,fitobj,func);
ROOT::Fit::Init2DGaus(data,func);
}
}
void GetTreeVarsAndCuts(TGComboBox* dataSet, TString& variablesStr, TString& cutsStr)
{
TGTextLBEntry* textEntry =
static_cast<TGTextLBEntry*>( dataSet->GetListBox()->GetEntry( dataSet->GetSelected() ) );
if (!textEntry) return;
TString nameStr ( textEntry->GetText()->GetString() );
variablesStr = nameStr(nameStr.First('(') + 2, nameStr.First(',') - nameStr.First('(') - 3);
cutsStr = nameStr( nameStr.First(',') + 3, nameStr.First(')') - nameStr.First(',') - 4 );
}
ClassImp(TFitEditor)
TFitEditor *TFitEditor::fgFitDialog = 0;
TFitEditor * TFitEditor::GetInstance(TVirtualPad* pad, TObject *obj)
{
if (!pad)
{
if (!gPad)
gROOT->MakeDefCanvas();
pad = gPad;
}
if (!fgFitDialog) {
fgFitDialog = new TFitEditor(pad, obj);
} else {
fgFitDialog->Show(pad, obj);
}
return fgFitDialog;
}
TFitEditor::TFitEditor(TVirtualPad* pad, TObject *obj) :
TGMainFrame(gClient->GetRoot(), 20, 20),
fParentPad (0),
fFitObject (0),
fDim (0),
fXaxis (0),
fYaxis (0),
fZaxis (0),
fFuncPars (0)
{
fType = kObjectHisto;
SetCleanup(kDeepCleanup);
TGCompositeFrame *tf = new TGCompositeFrame(this, 350, 26,
kHorizontalFrame);
TGLabel *label = new TGLabel(tf,"Data Set: ");
tf->AddFrame(label, new TGLayoutHints(kLHintsNormal, 15, 0, 5, 0));
fDataSet = new TGComboBox(tf, kFP_DATAS);
FillDataSetList();
fDataSet->Resize(264, 20);
tf->AddFrame(fDataSet, new TGLayoutHints(kLHintsNormal, 13, 0, 5, 0));
fDataSet->Associate(this);
this->AddFrame(tf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX,0,0,5,5));
CreateFunctionGroup();
fTab = new TGTab(this, 10, 10);
AddFrame(fTab, new TGLayoutHints(kLHintsExpandY | kLHintsExpandX));
fTab->SetCleanup(kDeepCleanup);
fTab->Associate(this);
TGHorizontalFrame *cf1 = new TGHorizontalFrame(this, 350, 20, kFixedWidth);
cf1->SetCleanup(kDeepCleanup);
fUpdateButton = new TGTextButton(cf1, "&Update", kFP_UPDATE);
fUpdateButton->Associate(this);
cf1->AddFrame(fUpdateButton, new TGLayoutHints(kLHintsTop |
kLHintsExpandX, 0, 20, 2, 2));
fFitButton = new TGTextButton(cf1, "&Fit", kFP_FIT);
fFitButton->Associate(this);
cf1->AddFrame(fFitButton, new TGLayoutHints(kLHintsTop |
kLHintsExpandX, 15, -6, 2, 2));
fResetButton = new TGTextButton(cf1, "&Reset", kFP_RESET);
fResetButton->Associate(this);
cf1->AddFrame(fResetButton, new TGLayoutHints(kLHintsTop |
kLHintsExpandX, 11, -2, 2, 2));
fCloseButton = new TGTextButton(cf1, "&Close", kFP_CLOSE);
fCloseButton->Associate(this);
cf1->AddFrame(fCloseButton, new TGLayoutHints(kLHintsTop |
kLHintsExpandX, 7, 2, 2, 2));
AddFrame(cf1, new TGLayoutHints(kLHintsNormal |
kLHintsRight, 0, 5, 5, 5));
int parts[] = { 20, 20, 20, 20, 20 };
fStatusBar = new TGStatusBar(this, 10, 10);
fStatusBar->SetParts(parts, 5);
AddFrame(fStatusBar, new TGLayoutHints(kLHintsBottom |
kLHintsLeft |
kLHintsExpandX));
CreateGeneralTab();
CreateMinimizationTab();
gROOT->GetListOfCleanups()->Add(this);
MapSubwindows();
fGeneral->HideFrame(fSliderZParent);
TGDimension size = GetDefaultSize();
SetWindowName("Fit Panel");
SetIconName("Fit Panel");
SetClassHints("ROOT", "Fit Panel");
SetMWMHints(kMWMDecorAll | kMWMDecorResizeH | kMWMDecorMaximize |
kMWMDecorMinimize | kMWMDecorMenu,
kMWMFuncAll | kMWMFuncResize | kMWMFuncMaximize |
kMWMFuncMinimize,
kMWMInputModeless);
ConnectSlots();
GetFunctionsFromSystem();
if (!obj) {
TList* l = new TList();
l->Add(pad);
std::vector<TObject*> v;
SearchCanvases(l, v);
if ( v.size() )
obj = v[0];
delete l;
}
SetFitObject(pad, obj, kButton1Down);
if ( pad ) {
SetCanvas(pad->GetCanvas());
if ( obj )
pad->GetCanvas()->Selected(pad, obj, kButton1Down);
}
UInt_t dw = fClient->GetDisplayWidth();
UInt_t cw = 0;
UInt_t cx = 0;
UInt_t cy = 0;
if (pad && pad->GetCanvas() ) {
cw = pad->GetCanvas()->GetWindowWidth();
cx = (UInt_t)pad->GetCanvas()->GetWindowTopX();
cy = (UInt_t)pad->GetCanvas()->GetWindowTopY();
}
Resize(size);
MapWindow();
if (cw + size.fWidth < dw) {
Int_t gedx = 0, gedy = 0;
gedx = cx+cw+4;
gedy = (cy > 20) ? cy-20 : 0;
MoveResize(gedx, gedy, size.fWidth, size.fHeight);
SetWMPosition(gedx, gedy);
}
gVirtualX->RaiseWindow(GetId());
ChangeOptions(GetOptions() | kFixedSize);
SetWMSize(size.fWidth, size.fHeight);
SetWMSizeHints(size.fWidth, size.fHeight, size.fWidth, size.fHeight, 0, 0);
}
TFitEditor::~TFitEditor()
{
DisconnectSlots();
fCloseButton->Disconnect("Clicked()");
fDataSet->Disconnect("Selected(Int_t)");
fUpdateButton->Disconnect("Clicked()");
TQObject::Disconnect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
this, "SetFitObject(TVirtualPad *, TObject *, Int_t)");
gROOT->GetListOfCleanups()->Remove(this);
Cleanup();
delete fLayoutNone;
delete fLayoutAdd;
delete fLayoutConv;
fgFitDialog = 0;
}
void TFitEditor::CreateFunctionGroup()
{
TGGroupFrame *gf1 = new TGGroupFrame(this, "Fit Function", kFitWidth);
TGCompositeFrame *tf0 = new TGCompositeFrame(gf1, 350, 26,
kHorizontalFrame);
TGLabel *label1 = new TGLabel(tf0,"Type:");
tf0->AddFrame(label1, new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0));
fTypeFit = new TGComboBox(tf0, kFP_TLIST);
fTypeFit->AddEntry("User Func", kFP_UFUNC);
fTypeFit->AddEntry("Predef-1D", kFP_PRED1D);
fTypeFit->Resize(90, 20);
fTypeFit->Select(kFP_PRED1D, kFALSE);
TGListBox *lb = fTypeFit->GetListBox();
lb->Resize(lb->GetWidth(), 200);
tf0->AddFrame(fTypeFit, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
fTypeFit->Associate(this);
fFuncList = new TGComboBox(tf0, kFP_FLIST);
FillFunctionList();
fFuncList->Resize(194, 20);
fFuncList->Select(kFP_GAUS, kFALSE);
lb = fFuncList->GetListBox();
lb->Resize(lb->GetWidth(), 500);
tf0->AddFrame(fFuncList, new TGLayoutHints(kLHintsNormal, 5, 0, 5, 0));
fFuncList->Associate(this);
gf1->AddFrame(tf0, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
TGCompositeFrame *tf1 = new TGCompositeFrame(gf1, 350, 26,
kHorizontalFrame);
TGHButtonGroup *bgr = new TGHButtonGroup(tf1, "Operation");
bgr->SetRadioButtonExclusive();
fNone = new TGRadioButton(bgr, "Nop", kFP_NONE);
fNone->SetToolTipText("No operation defined");
fNone->SetState(kButtonDown, kFALSE);
fAdd = new TGRadioButton(bgr, "Add", kFP_ADD);
fAdd->SetToolTipText("Addition");
fConv = new TGRadioButton(bgr, "Conv", kFP_CONV);
fConv->SetToolTipText("Convolution (not implemented yet)");
fConv->SetState(kButtonDisabled);
fLayoutNone = new TGLayoutHints(kLHintsLeft,0,5,3,-10);
fLayoutAdd = new TGLayoutHints(kLHintsLeft,10,5,3,-10);
fLayoutConv = new TGLayoutHints(kLHintsLeft,10,5,3,-10);
bgr->SetLayoutHints(fLayoutNone,fNone);
bgr->SetLayoutHints(fLayoutAdd,fAdd);
bgr->SetLayoutHints(fLayoutConv,fConv);
bgr->Show();
bgr->ChangeOptions(kFitWidth | kHorizontalFrame);
tf1->AddFrame(bgr, new TGLayoutHints(kLHintsExpandX, 0, 0, 3, 0));
gf1->AddFrame(tf1, new TGLayoutHints(kLHintsExpandX));
TGCompositeFrame *tf2 = new TGCompositeFrame(gf1, 350, 26,
kHorizontalFrame);
fEnteredFunc = new TGTextEntry(tf2, new TGTextBuffer(0), kFP_FILE);
fEnteredFunc->SetAlignment(kTextLeft);
TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
assert(te);
fEnteredFunc->SetText(te->GetTitle());
fEnteredFunc->SetToolTipText("Enter file_name/function_name or a function expression");
fEnteredFunc->Resize(250,fEnteredFunc->GetDefaultHeight());
tf2->AddFrame(fEnteredFunc, new TGLayoutHints(kLHintsLeft |
kLHintsCenterY |
kLHintsExpandX, 2, 2, 2, 2));
gf1->AddFrame(tf2, new TGLayoutHints(kLHintsNormal |
kLHintsExpandX, 0, 0, 2, 0));
TGHorizontalFrame *s1 = new TGHorizontalFrame(gf1);
TGLabel *label21 = new TGLabel(s1, "Selected: ");
s1->AddFrame(label21, new TGLayoutHints(kLHintsNormal |
kLHintsCenterY, 2, 2, 2, 0));
TGHorizontal3DLine *hlines = new TGHorizontal3DLine(s1);
s1->AddFrame(hlines, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
gf1->AddFrame(s1, new TGLayoutHints(kLHintsExpandX));
TGCompositeFrame *tf4 = new TGCompositeFrame(gf1, 350, 26,
kHorizontalFrame);
TGTextLBEntry *txt = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
TString s = txt->GetTitle();
fSelLabel = new TGLabel(tf4, s.Sizeof()>30?s(0,30)+"...":s);
tf4->AddFrame(fSelLabel, new TGLayoutHints(kLHintsNormal |
kLHintsCenterY, 0, 6, 2, 0));
Pixel_t color;
gClient->GetColorByName("#336666", color);
fSelLabel->SetTextColor(color, kFALSE);
TGCompositeFrame *tf5 = new TGCompositeFrame(tf4, 120, 20,
kHorizontalFrame | kFixedWidth);
fSetParam = new TGTextButton(tf5, "Set Parameters...", kFP_PARS);
tf5->AddFrame(fSetParam, new TGLayoutHints(kLHintsRight |
kLHintsCenterY |
kLHintsExpandX));
fSetParam->SetToolTipText("Open a dialog for parameter(s) settings");
tf4->AddFrame(tf5, new TGLayoutHints(kLHintsRight |
kLHintsTop, 5, 0, 2, 2));
gf1->AddFrame(tf4, new TGLayoutHints(kLHintsNormal |
kLHintsExpandX, 5, 0, 0, 0));
this->AddFrame(gf1, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
}
void TFitEditor::CreateGeneralTab()
{
fTabContainer = fTab->AddTab("General");
fGeneral = new TGCompositeFrame(fTabContainer, 10, 10, kVerticalFrame);
fTabContainer->AddFrame(fGeneral, new TGLayoutHints(kLHintsTop |
kLHintsExpandX,
5, 5, 2, 2));
TGGroupFrame *gf = new TGGroupFrame(fGeneral, "Fit Settings", kFitWidth);
TGHorizontalFrame *h1 = new TGHorizontalFrame(gf);
TGLabel *label4 = new TGLabel(h1, "Method");
h1->AddFrame(label4, new TGLayoutHints(kLHintsNormal |
kLHintsCenterY, 2, 2, 0, 0));
TGHorizontal3DLine *hline1 = new TGHorizontal3DLine(h1);
h1->AddFrame(hline1, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
gf->AddFrame(h1, new TGLayoutHints(kLHintsExpandX));
TGHorizontalFrame *h2 = new TGHorizontalFrame(gf);
TGVerticalFrame *v1 = new TGVerticalFrame(h2);
fMethodList = BuildMethodList(v1, kFP_MLIST);
fMethodList->Select(1, kFALSE);
fMethodList->Resize(140, 20);
TGListBox *lb = fMethodList->GetListBox();
Int_t lbe = lb->GetNumberOfEntries();
lb->Resize(lb->GetWidth(), lbe*16);
v1->AddFrame(fMethodList, new TGLayoutHints(kLHintsLeft, 0, 0, 2, 5));
fLinearFit = new TGCheckButton(v1, "Linear fit", kFP_MLINF);
fLinearFit->Associate(this);
fLinearFit->SetToolTipText("Perform Linear fitter if selected");
v1->AddFrame(fLinearFit, new TGLayoutHints(kLHintsNormal, 0, 0, 8, 2));
h2->AddFrame(v1, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
TGVerticalFrame *v2 = new TGVerticalFrame(h2);
TGCompositeFrame *v21 = new TGCompositeFrame(v2, 120, 20,
kHorizontalFrame | kFixedWidth);
fUserButton = new TGTextButton(v21, "User-Defined...", kFP_MUSR);
v21->AddFrame(fUserButton, new TGLayoutHints(kLHintsRight |
kLHintsCenterY |
kLHintsExpandX));
fUserButton->SetToolTipText("Open a dialog for entering a user-defined method");
fUserButton->SetState(kButtonDisabled);
v2->AddFrame(v21, new TGLayoutHints(kLHintsRight | kLHintsTop));
TGHorizontalFrame *v1h = new TGHorizontalFrame(v2);
fEnableRobust = new TGCheckButton(v1h, "Robust:", -1);
fEnableRobust->Associate(this);
fEnableRobust->SetToolTipText("Perform Linear Robust fitter if selected");
v1h->AddFrame(fEnableRobust, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
fRobustValue = new TGNumberEntry(v1h, 0.95, 5, kFP_RBUST,
TGNumberFormat::kNESRealTwo,
TGNumberFormat::kNEAPositive,
TGNumberFormat::kNELLimitMinMax,0.,0.99);
v1h->AddFrame(fRobustValue, new TGLayoutHints(kLHintsLeft));
v2->AddFrame(v1h, new TGLayoutHints(kLHintsNormal, 0, 0, 12, 2));
fRobustValue->SetState(kFALSE);
fRobustValue->GetNumberEntry()->SetToolTipText("Available only for graphs");
fNoChi2 = 0;
h2->AddFrame(v2, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 20, 0, 0, 0));
gf->AddFrame(h2, new TGLayoutHints(kLHintsExpandX, 20, 0, 0, 0));
TGHorizontalFrame *h3 = new TGHorizontalFrame(gf);
TGLabel *label5 = new TGLabel(h3, "Fit Options");
h3->AddFrame(label5, new TGLayoutHints(kLHintsNormal |
kLHintsCenterY, 2, 2, 0, 0));
TGHorizontal3DLine *hline2 = new TGHorizontal3DLine(h3);
h3->AddFrame(hline2, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
gf->AddFrame(h3, new TGLayoutHints(kLHintsExpandX));
TGHorizontalFrame *h = new TGHorizontalFrame(gf);
TGVerticalFrame *v3 = new TGVerticalFrame(h);
fIntegral = new TGCheckButton(v3, "Integral", kFP_INTEG);
fIntegral->Associate(this);
fIntegral->SetToolTipText("'I'- use integral of function instead of value in bin center");
v3->AddFrame(fIntegral, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
fBestErrors = new TGCheckButton(v3, "Best errors", kFP_IMERR);
fBestErrors->Associate(this);
fBestErrors->SetToolTipText("'E'- better errors estimation using Minos technique");
v3->AddFrame(fBestErrors, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
fAllWeights1 = new TGCheckButton(v3, "All weights = 1", kFP_ALLW1);
fAllWeights1->Associate(this);
fAllWeights1->SetToolTipText("'W'- all weights=1 for non empty bins; error bars ignored");
v3->AddFrame(fAllWeights1, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
fEmptyBinsWghts1 = new TGCheckButton(v3, "Empty bins, weights=1", kFP_EMPW1);
fEmptyBinsWghts1->Associate(this);
fEmptyBinsWghts1->SetToolTipText("'WW'- all weights=1 including empty bins; error bars ignored");
v3->AddFrame(fEmptyBinsWghts1, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
h->AddFrame(v3, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
TGVerticalFrame *v4 = new TGVerticalFrame(h);
fUseRange = new TGCheckButton(v4, "Use range", kFP_USERG);
fUseRange->Associate(this);
fUseRange->SetToolTipText("'R'- fit only data within the specified function range");
v4->AddFrame(fUseRange, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
fImproveResults = new TGCheckButton(v4, "Improve fit results", kFP_IFITR);
fImproveResults->Associate(this);
fImproveResults->SetToolTipText("'M'- after minimum is found, search for a new one");
v4->AddFrame(fImproveResults, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
fAdd2FuncList = new TGCheckButton(v4, "Add to list", kFP_ADDLS);
fAdd2FuncList->Associate(this);
fAdd2FuncList->SetToolTipText("'+'- add function to the list without deleting the previous");
v4->AddFrame(fAdd2FuncList, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
fUseGradient = new TGCheckButton(v4, "Use Gradient", kFP_ADDLS);
fUseGradient->Associate(this);
fUseGradient->SetToolTipText("'G'- Use the gradient as an aid for the fitting");
v4->AddFrame(fUseGradient, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
h->AddFrame(v4, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 20, 0, 0, 0));
gf->AddFrame(h, new TGLayoutHints(kLHintsExpandX, 20, 0, 0, 0));
TGHorizontalFrame *h5 = new TGHorizontalFrame(gf);
TGLabel *label6 = new TGLabel(h5, "Draw Options");
h5->AddFrame(label6, new TGLayoutHints(kLHintsNormal |
kLHintsCenterY, 2, 2, 2, 2));
TGHorizontal3DLine *hline3 = new TGHorizontal3DLine(h5);
h5->AddFrame(hline3, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX));
gf->AddFrame(h5, new TGLayoutHints(kLHintsExpandX));
TGHorizontalFrame *h6 = new TGHorizontalFrame(gf);
TGVerticalFrame *v5 = new TGVerticalFrame(h6);
fDrawSame = new TGCheckButton(v5, "SAME", kFP_DSAME);
fDrawSame->Associate(this);
fDrawSame->SetToolTipText("Superimpose on previous picture in the same pad");
v5->AddFrame(fDrawSame, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
fNoDrawing = new TGCheckButton(v5, "No drawing", kFP_DNONE);
fNoDrawing->Associate(this);
fNoDrawing->SetToolTipText("'0'- do not draw function graphics");
v5->AddFrame(fNoDrawing, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
fNoStoreDrawing = new TGCheckButton(v5, "Do not store/draw", kFP_DNOST);
fNoStoreDrawing->Associate(this);
fNoStoreDrawing->SetToolTipText("'N'- do not store the function, do not draw it");
v5->AddFrame(fNoStoreDrawing, new TGLayoutHints(kLHintsNormal, 0, 0, 2, 2));
h6->AddFrame(v5, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
TGVerticalFrame *v6 = new TGVerticalFrame(h6);
TGCompositeFrame *v61 = new TGCompositeFrame(v6, 120, 20,
kHorizontalFrame | kFixedWidth);
fDrawAdvanced = new TGTextButton(v61, "&Advanced...", kFP_DADVB);
v61->AddFrame(fDrawAdvanced, new TGLayoutHints(kLHintsRight |
kLHintsCenterY |
kLHintsExpandX));
fDrawAdvanced->SetToolTipText("Open a dialog for advanced draw options");
fDrawAdvanced->SetState(kButtonDisabled);
v6->AddFrame(v61, new TGLayoutHints(kLHintsRight | kLHintsTop,
0, 0, (4+fDrawSame->GetHeight())*2, 0));
h6->AddFrame(v6, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
gf->AddFrame(h6, new TGLayoutHints(kLHintsExpandX, 20, 0, 2, 0));
fGeneral->AddFrame(gf, new TGLayoutHints(kLHintsExpandX |
kLHintsExpandY, 5, 5, 0, 0));
fSliderXParent = new TGHorizontalFrame(fGeneral);
TGLabel *label8 = new TGLabel(fSliderXParent, "X");
fSliderXParent->AddFrame(label8, new TGLayoutHints(kLHintsLeft |
kLHintsCenterY, 0, 5, 0, 0));
fSliderXMin = new TGNumberEntry(fSliderXParent, 0, 5, kFP_XMIN,
TGNumberFormat::kNESRealTwo,
TGNumberFormat::kNEAAnyNumber,
TGNumberFormat::kNELLimitMinMax, -1,1);
fSliderXParent->AddFrame(fSliderXMin, new TGLayoutHints(kLHintsLeft | kLHintsCenterY));
fSliderX = new TGDoubleHSlider(fSliderXParent, 1, kDoubleScaleBoth);
fSliderX->SetScale(5);
fSliderXParent->AddFrame(fSliderX, new TGLayoutHints(kLHintsExpandX | kLHintsCenterY));
fSliderXMax = new TGNumberEntry(fSliderXParent, 0, 5, kFP_XMIN,
TGNumberFormat::kNESRealTwo,
TGNumberFormat::kNEAAnyNumber,
TGNumberFormat::kNELLimitMinMax, -1,1);
fSliderXParent->AddFrame(fSliderXMax, new TGLayoutHints(kLHintsRight | kLHintsCenterY));
fGeneral->AddFrame(fSliderXParent, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
fSliderYParent = new TGHorizontalFrame(fGeneral);
TGLabel *label9 = new TGLabel(fSliderYParent, "Y");
fSliderYParent->AddFrame(label9, new TGLayoutHints(kLHintsLeft |
kLHintsCenterY, 0, 5, 0, 0));
fSliderYMin = new TGNumberEntry(fSliderYParent, 0, 5, kFP_YMIN,
TGNumberFormat::kNESRealTwo,
TGNumberFormat::kNEAAnyNumber,
TGNumberFormat::kNELLimitMinMax, -1,1);
fSliderYParent->AddFrame(fSliderYMin, new TGLayoutHints(kLHintsLeft | kLHintsCenterY));
fSliderY = new TGDoubleHSlider(fSliderYParent, 1, kDoubleScaleBoth);
fSliderY->SetScale(5);
fSliderYParent->AddFrame(fSliderY, new TGLayoutHints(kLHintsExpandX | kLHintsCenterY));
fSliderYMax = new TGNumberEntry(fSliderYParent, 0, 5, kFP_YMIN,
TGNumberFormat::kNESRealTwo,
TGNumberFormat::kNEAAnyNumber,
TGNumberFormat::kNELLimitMinMax, -1,1);
fSliderYParent->AddFrame(fSliderYMax, new TGLayoutHints(kLHintsRight | kLHintsCenterY));
fGeneral->AddFrame(fSliderYParent, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
fSliderZParent = new TGHorizontalFrame(fGeneral);
TGLabel *label10 = new TGLabel(fSliderZParent, "Z:");
fSliderZParent->AddFrame(label10, new TGLayoutHints(kLHintsLeft |
kLHintsCenterY, 0, 5, 0, 0));
fSliderZ = new TGDoubleHSlider(fSliderZParent, 1, kDoubleScaleBoth);
fSliderZ->SetScale(5);
fSliderZParent->AddFrame(fSliderZ, new TGLayoutHints(kLHintsExpandX |
kLHintsCenterY));
fGeneral->AddFrame(fSliderZParent, new TGLayoutHints(kLHintsExpandX, 5, 5, 0, 0));
}
void TFitEditor::CreateMinimizationTab()
{
fTabContainer = fTab->AddTab("Minimization");
fMinimization = new TGCompositeFrame(fTabContainer, 10, 10, kVerticalFrame);
fTabContainer->AddFrame(fMinimization, new TGLayoutHints(kLHintsTop |
kLHintsExpandX,
5, 5, 2, 2));
MakeTitle(fMinimization, "Library");
TGHorizontalFrame *hl = new TGHorizontalFrame(fMinimization);
fLibMinuit = new TGRadioButton(hl, "Minuit", kFP_LMIN);
fLibMinuit->Associate(this);
fLibMinuit->SetToolTipText("Use minimization from libMinuit (default)");
hl->AddFrame(fLibMinuit, new TGLayoutHints(kLHintsNormal, 40, 0, 0, 1));
fStatusBar->SetText("LIB Minuit",1);
fLibMinuit2 = new TGRadioButton(hl, "Minuit2", kFP_LMIN2);
fLibMinuit2->Associate(this);
fLibMinuit2->SetToolTipText("New C++ version of Minuit");
hl->AddFrame(fLibMinuit2, new TGLayoutHints(kLHintsNormal, 35, 0, 0, 1));
fLibFumili = new TGRadioButton(hl, "Fumili", kFP_LFUM);
fLibFumili->Associate(this);
fLibFumili->SetToolTipText("Use minimization from libFumili");
hl->AddFrame(fLibFumili, new TGLayoutHints(kLHintsNormal, 30, 0, 0, 1));
fMinimization->AddFrame(hl, new TGLayoutHints(kLHintsExpandX, 20, 0, 5, 1));
TGHorizontalFrame *hl2 = new TGHorizontalFrame(fMinimization);
fLibGSL = new TGRadioButton(hl2, "GSL", kFP_LGSL);
#ifdef R__HAS_MATHMORE
fLibGSL->Associate(this);
fLibGSL->SetToolTipText("Use minimization from libGSL");
#else
fLibGSL->SetState(kButtonDisabled);
fLibGSL->SetToolTipText("Needs GSL to be compiled");
#endif
hl2->AddFrame(fLibGSL, new TGLayoutHints(kLHintsNormal, 40, 0, 0, 1));
fLibGenetics = new TGRadioButton(hl2, "Genetics", kFP_LGAS);
if (gPluginMgr->FindHandler("ROOT::Math::Minimizer","Genetic") ||
gPluginMgr->FindHandler("ROOT::Math::Minimizer","GAlibMin") )
{
fLibGenetics->Associate(this);
fLibGenetics->SetToolTipText("Different GAs implementations");
} else {
fLibGenetics->SetState(kButtonDisabled);
fLibGenetics->SetToolTipText("Needs any of the genetic"
"minimizers to be compiled");
}
hl2->AddFrame(fLibGenetics, new TGLayoutHints(kLHintsNormal, 45, 0, 0, 1));
fMinimization->AddFrame(hl2, new TGLayoutHints(kLHintsExpandX, 20, 0, 5, 1));
MakeTitle(fMinimization, "Method");
TGHorizontalFrame *hm0 = new TGHorizontalFrame(fMinimization);
fMinMethodList = new TGComboBox(hm0, kFP_MINMETHOD);
fMinMethodList->Resize(290, 20);
fMinMethodList->Select(kFP_GAUS, kFALSE);
TGListBox *lb = fMinMethodList->GetListBox();
lb->Resize(lb->GetWidth(), 500);
fMinMethodList->Associate(this);
hm0->AddFrame(fMinMethodList, new TGLayoutHints(kLHintsNormal));
fMinimization->AddFrame(hm0, new TGLayoutHints(kLHintsExpandX, 60, 0, 5, 1));
if ( ROOT::Math::MinimizerOptions::DefaultMinimizerType() == "Fumili" ) {
fLibFumili->SetState(kButtonDown);
} else if ( ROOT::Math::MinimizerOptions::DefaultMinimizerType() == "Minuit" ) {
fLibMinuit->SetState(kButtonDown);
} else {
fLibMinuit2->SetState(kButtonDown);
}
FillMinMethodList();
MakeTitle(fMinimization, "Settings");
TGLabel *hslabel1 = new TGLabel(fMinimization,"Use ENTER key to validate a new value or click");
fMinimization->AddFrame(hslabel1, new TGLayoutHints(kLHintsNormal, 61, 0, 5, 1));
TGLabel *hslabel2 = new TGLabel(fMinimization,"on Reset button to set the defaults.");
fMinimization->AddFrame(hslabel2, new TGLayoutHints(kLHintsNormal, 61, 0, 1, 10));
TGHorizontalFrame *hs = new TGHorizontalFrame(fMinimization);
TGVerticalFrame *hsv1 = new TGVerticalFrame(hs, 180, 10, kFixedWidth);
TGLabel *errlabel = new TGLabel(hsv1,"Error definition (default = 1): ");
hsv1->AddFrame(errlabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
1, 1, 5, 7));
TGLabel *tollabel = new TGLabel(hsv1,"Max tolerance (precision): ");
hsv1->AddFrame(tollabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
1, 1, 5, 7));
TGLabel *itrlabel = new TGLabel(hsv1,"Max number of iterations: ");
hsv1->AddFrame(itrlabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
1, 1, 5, 5));
hs->AddFrame(hsv1, new TGLayoutHints(kLHintsNormal, 60, 0, 0, 0));
TGVerticalFrame *hsv2 = new TGVerticalFrame(hs, 90,10, kFixedWidth);
fErrorScale = new TGNumberEntryField(hsv2, kFP_MERR, ROOT::Math::MinimizerOptions::DefaultErrorDef(),
TGNumberFormat::kNESRealTwo,
TGNumberFormat::kNEAPositive,
TGNumberFormat::kNELLimitMinMax,0.,100.);
hsv2->AddFrame(fErrorScale, new TGLayoutHints(kLHintsLeft | kLHintsExpandX,
1, 1, 0, 3));
fTolerance = new TGNumberEntryField(hsv2, kFP_MTOL, ROOT::Math::MinimizerOptions::DefaultTolerance(),
TGNumberFormat::kNESReal,
TGNumberFormat::kNEAPositive,
TGNumberFormat::kNELLimitMinMax, 0., 1.);
fTolerance->SetNumber(ROOT::Math::MinimizerOptions::DefaultTolerance());
hsv2->AddFrame(fTolerance, new TGLayoutHints(kLHintsLeft | kLHintsExpandX,
1, 1, 3, 3));
fIterations = new TGNumberEntryField(hsv2, kFP_MITR, 5000,
TGNumberFormat::kNESInteger,
TGNumberFormat::kNEAPositive,
TGNumberFormat::kNELNoLimits);
fIterations->SetNumber(ROOT::Math::MinimizerOptions::DefaultMaxIterations());
hsv2->AddFrame(fIterations, new TGLayoutHints(kLHintsLeft | kLHintsExpandX,
1, 1, 3, 3));
hs->AddFrame(hsv2, new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
fMinimization->AddFrame(hs, new TGLayoutHints(kLHintsExpandX, 0, 0, 1, 1));
fStatusBar->SetText(Form("Itr: %d",ROOT::Math::MinimizerOptions::DefaultMaxIterations()),3);
MakeTitle(fMinimization, "Print Options");
TGHorizontalFrame *h8 = new TGHorizontalFrame(fMinimization);
fOptDefault = new TGRadioButton(h8, "Default", kFP_PDEF);
fOptDefault->Associate(this);
fOptDefault->SetToolTipText("Default is between Verbose and Quiet");
h8->AddFrame(fOptDefault, new TGLayoutHints(kLHintsNormal, 40, 0, 0, 1));
fOptDefault->SetState(kButtonDown);
fStatusBar->SetText("Prn: DEF",4);
fOptVerbose = new TGRadioButton(h8, "Verbose", kFP_PVER);
fOptVerbose->Associate(this);
fOptVerbose->SetToolTipText("'V'- print results after each iteration");
h8->AddFrame(fOptVerbose, new TGLayoutHints(kLHintsNormal, 30, 0, 0, 1));
fOptQuiet = new TGRadioButton(h8, "Quiet", kFP_PQET);
fOptQuiet->Associate(this);
fOptQuiet->SetToolTipText("'Q'- no print");
h8->AddFrame(fOptQuiet, new TGLayoutHints(kLHintsNormal, 25, 0, 0, 1));
fMinimization->AddFrame(h8, new TGLayoutHints(kLHintsExpandX, 20, 0, 5, 1));
}
void TFitEditor::ConnectSlots()
{
fDataSet->Connect("Selected(Int_t)", "TFitEditor", this, "DoDataSet(Int_t)");
fTypeFit->Connect("Selected(Int_t)", "TFitEditor", this, "FillFunctionList(Int_t)");
fFuncList->Connect("Selected(Int_t)", "TFitEditor", this, "DoFunction(Int_t)");
fEnteredFunc->Connect("ReturnPressed()", "TFitEditor", this, "DoEnteredFunction()");
fSetParam->Connect("Clicked()", "TFitEditor", this, "DoSetParameters()");
fAdd->Connect("Toggled(Bool_t)","TFitEditor", this, "DoAddition(Bool_t)");
fAllWeights1->Connect("Toggled(Bool_t)","TFitEditor",this,"DoAllWeights1()");
fUseRange->Connect("Toggled(Bool_t)","TFitEditor",this,"DoUseFuncRange()");
fEmptyBinsWghts1->Connect("Toggled(Bool_t)","TFitEditor",this,"DoEmptyBinsAllWeights1()");
fLinearFit->Connect("Toggled(Bool_t)","TFitEditor",this,"DoLinearFit()");
fEnableRobust->Connect("Toggled(Bool_t)","TFitEditor",this,"DoRobustFit()");
fNoStoreDrawing->Connect("Toggled(Bool_t)","TFitEditor",this,"DoNoStoreDrawing()");
fUpdateButton->Connect("Clicked()", "TFitEditor", this, "DoUpdate()");
fFitButton->Connect("Clicked()", "TFitEditor", this, "DoFit()");
fResetButton->Connect("Clicked()", "TFitEditor", this, "DoReset()");
fCloseButton->Connect("Clicked()", "TFitEditor", this, "DoClose()");
fUserButton->Connect("Clicked()", "TFitEditor", this, "DoUserDialog()");
fDrawAdvanced->Connect("Clicked()", "TFitEditor", this, "DoAdvancedOptions()");
if (fType != kObjectTree) {
fSliderX->Connect("PositionChanged()","TFitEditor",this, "DoSliderXMoved()");
fSliderXMax->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderXChanged()");
fSliderXMin->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderXChanged()");
}
if (fDim > 1) {
fSliderY->Connect("PositionChanged()","TFitEditor",this, "DoSliderYMoved()");
fSliderYMax->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderYChanged()");
fSliderYMin->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderYChanged()");
}
if (fDim > 2)
fSliderZ->Connect("PositionChanged()","TFitEditor",this, "DoSliderZMoved()");
if ( fParentPad )
fParentPad->Connect("RangeAxisChanged()", "TFitEditor", this, "UpdateGUI()");
fLibMinuit->Connect("Toggled(Bool_t)","TFitEditor",this,"DoLibrary(Bool_t)");
fLibMinuit2->Connect("Toggled(Bool_t)","TFitEditor",this,"DoLibrary(Bool_t)");
fLibFumili->Connect("Toggled(Bool_t)","TFitEditor",this,"DoLibrary(Bool_t)");
fLibGSL->Connect("Toggled(Bool_t)","TFitEditor",this,"DoLibrary(Bool_t)");
fLibGenetics->Connect("Toggled(Bool_t)","TFitEditor",this,"DoLibrary(Bool_t)");
fMinMethodList->Connect("Selected(Int_t)", "TFitEditor", this, "DoMinMethod(Int_t)");
fIterations->Connect("ReturnPressed()", "TFitEditor", this, "DoMaxIterations()");
fOptDefault->Connect("Toggled(Bool_t)","TFitEditor",this,"DoPrintOpt(Bool_t)");
fOptVerbose->Connect("Toggled(Bool_t)","TFitEditor",this,"DoPrintOpt(Bool_t)");
fOptQuiet->Connect("Toggled(Bool_t)","TFitEditor",this,"DoPrintOpt(Bool_t)");
}
void TFitEditor::DisconnectSlots()
{
Disconnect("CloseWindow()");
fFuncList->Disconnect("Selected(Int_t)");
fEnteredFunc->Disconnect("ReturnPressed()");
fSetParam->Disconnect("Clicked()");
fAdd->Disconnect("Toggled(Bool_t)");
fAllWeights1->Disconnect("Toggled(Bool_t)");
fEmptyBinsWghts1->Disconnect("Toggled(Bool_t)");
fLinearFit->Disconnect("Toggled(Bool_t)");
fEnableRobust->Disconnect("Toggled(Bool_t)");
fNoStoreDrawing->Disconnect("Toggled(Bool_t)");
fFitButton->Disconnect("Clicked()");
fResetButton->Disconnect("Clicked()");
fUserButton->Disconnect("Clicked()");
fDrawAdvanced->Disconnect("Clicked()");
if (fType != kObjectTree) {
fSliderX->Disconnect("PositionChanged()");
fSliderXMax->Disconnect("ValueChanged(Long_t)");
fSliderXMin->Disconnect("ValueChanged(Long_t)");
}
if (fDim > 1) {
fSliderY->Disconnect("PositionChanged()");
fSliderYMax->Disconnect("ValueChanged(Long_t)");
fSliderYMin->Disconnect("ValueChanged(Long_t)");
}
if (fDim > 2)
fSliderZ->Disconnect("PositionChanged()");
fLibMinuit->Disconnect("Toggled(Bool_t)");
fLibMinuit2->Disconnect("Toggled(Bool_t)");
fLibFumili->Disconnect("Toggled(Bool_t)");
fLibGSL->Disconnect("Toggled(Bool_t)");
fLibGenetics->Disconnect("Toggled(Bool_t)");
fMinMethodList->Disconnect("Selected(Int_t)");
fIterations->Disconnect("ReturnPressed()");
fOptDefault->Disconnect("Toggled(Bool_t)");
fOptVerbose->Disconnect("Toggled(Bool_t)");
fOptQuiet->Disconnect("Toggled(Bool_t)");
}
void TFitEditor::SetCanvas(TCanvas * )
{
TQObject::Connect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
"TFitEditor",this,
"SetFitObject(TVirtualPad *, TObject *, Int_t)");
TQObject::Connect("TCanvas", "Closed()", "TFitEditor", this, "DoNoSelection()");
}
void TFitEditor::Hide()
{
if (fgFitDialog) {
fgFitDialog->UnmapWindow();
}
if (fParentPad) {
fParentPad->Disconnect("RangeAxisChanged()");
DoReset();
}
fParentPad = 0;
fFitObject = 0;
gROOT->GetListOfCleanups()->Remove(this);
}
void TFitEditor::Show(TVirtualPad* pad, TObject *obj)
{
if (!gROOT->GetListOfCleanups()->FindObject(this))
gROOT->GetListOfCleanups()->Add(this);
if (!fgFitDialog->IsMapped()) {
fgFitDialog->MapWindow();
gVirtualX->RaiseWindow(GetId());
}
fParentPad = static_cast<TPad*>(pad);
SetCanvas(pad->GetCanvas());
SetFitObject(pad, obj, kButton1Down);
}
void TFitEditor::CloseWindow()
{
Hide();
}
void TFitEditor::Terminate()
{
TQObject::Disconnect("TCanvas", "Closed()");
delete fgFitDialog;
fgFitDialog = 0;
}
void TFitEditor::UpdateGUI()
{
if (!fFitObject) return;
DrawSelection(true);
if ( fType == kObjectTree )
return;
if (fType != kObjectTree) {
TH1* hist = 0;
switch (fType) {
case kObjectHisto:
hist = (TH1*)fFitObject;
break;
case kObjectGraph:
hist = ((TGraph*)fFitObject)->GetHistogram();
break;
case kObjectMultiGraph:
hist = ((TMultiGraph*)fFitObject)->GetHistogram();
break;
case kObjectGraph2D:
hist = ((TGraph2D*)fFitObject)->GetHistogram("empty");
break;
case kObjectHStack:
hist = (TH1 *)((THStack *)fFitObject)->GetHists()->First();
case kObjectTree:
default:
break;
}
if (!hist) {
Error("UpdateGUI","No hist is present - this should not happen, please report."
"The FitPanel might be in an inconsistent state");
return;
}
fSliderX->Disconnect("PositionChanged()");
fSliderXMin->Disconnect("ValueChanged()");
fSliderXMax->Disconnect("ValueChanged()");
if (!fSliderXParent->IsMapped())
fSliderXParent->MapWindow();
fXaxis = hist->GetXaxis();
fYaxis = hist->GetYaxis();
fZaxis = hist->GetZaxis();
Int_t ixrange = fXaxis->GetNbins();
Int_t ixmin = fXaxis->GetFirst();
Int_t ixmax = fXaxis->GetLast();
if (ixmin > 1 || ixmax < ixrange) {
fSliderX->SetRange(ixmin,ixmax);
fSliderX->SetPosition(ixmin, ixmax);
} else {
fSliderX->SetRange(1,ixrange);
fSliderX->SetPosition(ixmin,ixmax);
}
fSliderX->SetScale(5);
fSliderXMin->SetLimits(TGNumberFormat::kNELLimitMinMax,
fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ),
fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ));
fSliderXMax->SetLimits(TGNumberFormat::kNELLimitMinMax,
fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ),
fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ));
fSliderX->Connect("PositionChanged()","TFitEditor",this, "DoSliderXMoved()");
fSliderXMax->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderXChanged()");
fSliderXMin->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderXChanged()");
}
if (fDim > 1) {
fSliderY->Disconnect("PositionChanged()");
fSliderYMin->Disconnect("ValueChanged()");
fSliderYMax->Disconnect("ValueChanged()");
if (!fSliderYParent->IsMapped())
fSliderYParent->MapWindow();
if (fSliderZParent->IsMapped())
fSliderZParent->UnmapWindow();
Int_t iymin = 0, iymax = 0, iyrange = 0;
switch (fType) {
case kObjectHisto:
case kObjectGraph2D:
case kObjectHStack:
iyrange = fYaxis->GetNbins();
iymin = fYaxis->GetFirst();
iymax = fYaxis->GetLast();
break;
case kObjectGraph:
case kObjectMultiGraph:
case kObjectTree:
default:
break;
}
if (iymin > 1 || iymax < iyrange) {
fSliderY->SetRange(iymin,iymax);
fSliderY->SetPosition(iymin, iymax);
} else {
fSliderY->SetRange(1,iyrange);
fSliderY->SetPosition(iymin,iymax);
}
fSliderY->SetScale(5);
fSliderYMin->SetLimits(TGNumberFormat::kNELLimitMinMax,
fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ),
fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
fSliderYMin->SetNumber(fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ));
fSliderYMax->SetLimits(TGNumberFormat::kNELLimitMinMax,
fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ),
fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ));
fSliderY->Connect("PositionChanged()","TFitEditor",this, "DoSliderYMoved()");
fSliderYMax->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderYChanged()");
fSliderYMin->Connect("ValueSet(Long_t)", "TFitEditor", this, "DoNumericSliderYChanged()");
}
if (fDim > 2) {
fSliderZ->Disconnect("PositionChanged()");
if (!fSliderZParent->IsMapped())
fSliderZParent->MapWindow();
Int_t izmin = 0, izmax = 0, izrange = 0;
switch (fType) {
case kObjectHStack:
case kObjectHisto:
izrange = fZaxis->GetNbins();
izmin = fZaxis->GetFirst();
izmax = fZaxis->GetLast();
break;
case kObjectGraph:
case kObjectGraph2D:
case kObjectMultiGraph:
case kObjectTree:
default:
break;
}
if (izmin > 1 || izmax < izrange) {
fSliderZ->SetRange(izmin,izmax);
fSliderZ->SetPosition(izmin, izmax);
} else {
fSliderZ->SetRange(1,izrange);
fSliderZ->SetPosition(izmin,izmax);
}
fSliderZ->SetScale(5);
fSliderZ->Connect("PositionChanged()","TFitEditor",this, "DoSliderZMoved()");
}
}
void TFitEditor::SetFitObject(TVirtualPad *pad, TObject *obj, Int_t event)
{
if (event != kButton1Down) return;
if ( !obj ) {
DoNoSelection();
return;
}
if (!SetObjectType(obj)) return;
fParentPad = pad;
fFitObject = obj;
ShowObjectName(obj);
UpdateGUI();
ConnectSlots();
TF1* fitFunc = HasFitFunction();
if (fitFunc) {
GetParameters(fFuncPars, fitFunc);
TString tmpStr = fitFunc->GetExpFormula();
TGLBEntry *en = 0;
if ( tmpStr.Length() == 0 )
{
fEnteredFunc->SetText(fitFunc->GetName());
en= fFuncList->FindEntry(fitFunc->GetName());
SetEditable(kFALSE);
}
else
{
fEnteredFunc->SetText(fitFunc->GetExpFormula().Data());
en= fFuncList->FindEntry(fitFunc->GetExpFormula().Data());
SetEditable(kTRUE);
}
if (en) fFuncList->Select(en->EntryId());
} else {
TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
if (te && fNone->GetState() == kButtonDown)
fEnteredFunc->SetText(te->GetTitle());
else if (te && fAdd->GetState() == kButtonDown) {
TString tmpStr = fEnteredFunc->GetText();
tmpStr += '+';
tmpStr +=te->GetTitle();
fEnteredFunc->SetText(tmpStr);
} else if ( !te )
fEnteredFunc->SetText(" ");
}
fEnteredFunc->SelectAll();
if (fSetParam->GetState() == kButtonDisabled)
fSetParam->SetEnabled(kTRUE);
if (fFitButton->GetState() == kButtonDisabled)
fFitButton->SetEnabled(kTRUE);
if (fResetButton->GetState() == kButtonDisabled)
fResetButton->SetEnabled(kTRUE);
DoLinearFit();
}
void TFitEditor::DoNoSelection()
{
if (gROOT->GetListOfCanvases()->IsEmpty()) {
Terminate();
return;
}
DisconnectSlots();
fParentPad = 0;
fFitObject = 0;
fStatusBar->SetText("No selection",0);
fDataSet->Select(kFP_NOSEL, kFALSE);
Layout();
fSetParam->SetEnabled(kFALSE);
fFitButton->SetEnabled(kFALSE);
fResetButton->SetEnabled(kFALSE);
fDrawAdvanced->SetState(kButtonDisabled);
}
void TFitEditor::RecursiveRemove(TObject* obj)
{
if (obj == fFitObject) {
fFitObject = 0;
DisconnectSlots();
fStatusBar->SetText("No selection",0);
fDataSet->Select(kFP_NOSEL, kFALSE);
Layout();
fFitButton->SetEnabled(kFALSE);
fResetButton->SetEnabled(kFALSE);
fSetParam->SetEnabled(kFALSE);
TQObject::Connect("TCanvas", "Selected(TVirtualPad *, TObject *, Int_t)",
"TFitEditor",this,
"SetFitObject(TVirtualPad *, TObject *, Int_t)");
TQObject::Connect("TCanvas", "Closed()", "TFitEditor", this,
"DoNoSelection()");
DoUpdate();
return;
}
if (obj == fParentPad) {
fFitObject = 0;
fParentPad = 0;
DisconnectSlots();
fStatusBar->SetText("No selection",0);
fDataSet->Select(kFP_NOSEL, kFALSE);
Layout();
fFitButton->SetEnabled(kFALSE);
fResetButton->SetEnabled(kFALSE);
fSetParam->SetEnabled(kFALSE);
}
}
void TFitEditor::FillFunctionList(Int_t)
{
fFuncList->RemoveAll();
if ( fTypeFit->GetSelected() == kFP_PRED1D && fDim <= 1 ) {
fFuncList->AddEntry("gaus" , kFP_GAUS);
fFuncList->AddEntry("gausn", kFP_GAUSN);
fFuncList->AddEntry("expo", kFP_EXPO);
fFuncList->AddEntry("landau", kFP_LAND);
fFuncList->AddEntry("landaun",kFP_LANDN);
fFuncList->AddEntry("pol0", kFP_POL0);
fFuncList->AddEntry("pol1", kFP_POL1);
fFuncList->AddEntry("pol2", kFP_POL2);
fFuncList->AddEntry("pol3", kFP_POL3);
fFuncList->AddEntry("pol4", kFP_POL4);
fFuncList->AddEntry("pol5", kFP_POL5);
fFuncList->AddEntry("pol6", kFP_POL6);
fFuncList->AddEntry("pol7", kFP_POL7);
fFuncList->AddEntry("pol8", kFP_POL8);
fFuncList->AddEntry("pol9", kFP_POL9);
fFuncList->AddEntry("user", kFP_USER);
TGListBox *lb = fFuncList->GetListBox();
lb->Resize(lb->GetWidth(), 200);
fFuncList->Select(kFP_GAUS);
}
else if ( fTypeFit->GetSelected() == kFP_PRED2D && fDim == 2 ) {
fFuncList->AddEntry("xygaus", kFP_XYGAUS);
fFuncList->AddEntry("xyexpo", kFP_XYEXP);
fFuncList->AddEntry("xylandau", kFP_XYLAN);
fFuncList->AddEntry("xylandaun", kFP_XYLANN);
TGListBox *lb = fFuncList->GetListBox();
lb->Resize(lb->GetWidth(), 200);
fFuncList->Select(kFP_XYGAUS);
}
else if ( fTypeFit->GetSelected() == kFP_UFUNC ) {
Int_t newid = kFP_ALTFUNC;
for ( fSystemFuncIter it = fSystemFuncs.begin();
it != fSystemFuncs.end(); ++it ) {
TF1* f = (*it);
if ( strncmp(f->GetName(), "PrevFit", 7) != 0 ) {
if ( f->GetNdim() == fDim || fDim == 0) {
fFuncList->AddEntry(f->GetName(), newid++);
}
}
}
if ( newid != kFP_ALTFUNC )
fFuncList->Select(newid-1);
else if( fDim == 1 ) {
fTypeFit->Select(kFP_PRED1D, kTRUE);
} else if( fDim == 2 ) {
fTypeFit->Select(kFP_PRED2D, kTRUE);
}
}
else if ( fTypeFit->GetSelected() == kFP_PREVFIT ) {
Int_t newid = kFP_ALTFUNC;
std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(fFitObject);
for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
fFuncList->AddEntry(it->second->GetName(), newid++);
}
if ( newid == kFP_ALTFUNC ) {
fTypeFit->RemoveEntry(kFP_PREVFIT);
if( fDim == 1 )
fTypeFit->Select(kFP_PRED1D, kTRUE);
else if ( fDim == 2 )
fTypeFit->Select(kFP_PRED2D, kTRUE);
else
fTypeFit->Select(kFP_UFUNC, kTRUE);
}
else
fFuncList->Select(newid-1, kTRUE);
}
}
void TFitEditor::FillMinMethodList(Int_t)
{
fMinMethodList->RemoveAll();
if ( fLibMinuit->GetState() == kButtonDown )
{
fMinMethodList->AddEntry("MIGRAD" , kFP_MIGRAD);
fMinMethodList->AddEntry("SIMPLEX" , kFP_SIMPLX);
fMinMethodList->AddEntry("SCAN" , kFP_SCAN);
fMinMethodList->AddEntry("Combination" , kFP_COMBINATION);
fMinMethodList->Select(kFP_MIGRAD, kFALSE);
fStatusBar->SetText("MIGRAD",2);
} else if ( fLibFumili->GetState() == kButtonDown )
{
fMinMethodList->AddEntry("FUMILI" , kFP_FUMILI);
fMinMethodList->Select(kFP_FUMILI, kFALSE);
fStatusBar->SetText("FUMILI",2);
} else if ( fLibGSL->GetState() == kButtonDown )
{
fMinMethodList->AddEntry("Fletcher-Reeves conjugate gradient" , kFP_GSLFR);
fMinMethodList->AddEntry("Polak-Ribiere conjugate gradient" , kFP_GSLPR);
fMinMethodList->AddEntry("BFGS conjugate gradient" , kFP_BFGS);
fMinMethodList->AddEntry("BFGS conjugate gradient (Version 2)", kFP_BFGS2);
fMinMethodList->AddEntry("Levenberg-Marquardt" , kFP_GSLLM);
fMinMethodList->AddEntry("Simulated Annealing" , kFP_GSLSA);
fMinMethodList->Select(kFP_GSLFR, kFALSE);
fStatusBar->SetText("CONJFR",2);
} else if ( fLibGenetics->GetState() == kButtonDown )
{
if ( gPluginMgr->FindHandler("ROOT::Math::Minimizer","GAlibMin") ) {
fMinMethodList->AddEntry("GA Lib Genetic Algorithm" , kFP_GALIB);
fMinMethodList->Select(kFP_GALIB, kFALSE);
} else if (gPluginMgr->FindHandler("ROOT::Math::Minimizer","Genetic")) {
fMinMethodList->AddEntry("TMVA Genetic Algorithm" , kFP_TMVAGA);
fMinMethodList->Select(kFP_TMVAGA, kFALSE);
}
} else
{
fMinMethodList->AddEntry("MIGRAD" , kFP_MIGRAD);
fMinMethodList->AddEntry("SIMPLEX" , kFP_SIMPLX);
fMinMethodList->AddEntry("FUMILI" , kFP_FUMILI);
fMinMethodList->AddEntry("SCAN" , kFP_SCAN);
fMinMethodList->AddEntry("Combination" , kFP_COMBINATION);
fMinMethodList->Select(kFP_MIGRAD, kFALSE);
fStatusBar->SetText("MIGRAD",2);
}
}
void SearchCanvases(TSeqCollection* canvases, std::vector<TObject*>& objects)
{
TIter canvasIter(canvases);
while(TObject* obj = (TObject*) canvasIter()) {
if ( TPad* can = dynamic_cast<TPad*>(obj))
SearchCanvases(can->GetListOfPrimitives(), objects);
else if ( dynamic_cast<TH1*>(obj)
|| dynamic_cast<TGraph*>(obj)
|| dynamic_cast<TGraph2D*>(obj)
|| dynamic_cast<TMultiGraph*>(obj)
|| dynamic_cast<THStack*>(obj)
|| dynamic_cast<TTree*>(obj) ) {
bool insertNew = true;
for ( std::vector<TObject*>::iterator i = objects.begin(); i != objects.end(); ++i )
if ( (*i) == obj ) {
insertNew = false;
break;
}
if ( insertNew ) objects.push_back(obj);
}
}
}
void TFitEditor::FillDataSetList()
{
TGTextLBEntry * entry = (TGTextLBEntry*) fDataSet->GetSelectedEntry();
TString selEntryStr;
if ( entry ) {
selEntryStr = entry->GetTitle();
}
fDataSet->RemoveAll();
std::vector<TObject*> objects;
TIter next(gDirectory->GetList());
TObject* obj = NULL;
while ( (obj = (TObject*) next()) ) {
if ( dynamic_cast<TH1*>(obj) ||
dynamic_cast<TGraph2D*>(obj) ||
dynamic_cast<TTree*>(obj) ) {
objects.push_back(obj);
}
}
SearchCanvases(gROOT->GetListOfCanvases(), objects);
int selected = kFP_NOSEL;
Int_t newid = kFP_NOSEL;
fDataSet->AddEntry("No Selection", newid++);
for ( std::vector<TObject*>::iterator i = objects.begin(); i != objects.end(); ++i ) {
TString name = (*i)->ClassName(); name.Append("::"); name.Append((*i)->GetName());
if ( selEntryStr && name == selEntryStr )
selected = newid;
fDataSet->AddEntry(name, newid++);
}
if (entry) {
fDataSet->Select(selected);
}
}
TGComboBox* TFitEditor::BuildMethodList(TGFrame* parent, Int_t id)
{
TGComboBox *c = new TGComboBox(parent, id);
c->AddEntry("Chi-square", kFP_MCHIS);
c->AddEntry("Binned Likelihood", kFP_MBINL);
c->AddEntry("Unbinned Likelihood", kFP_MUBIN);
c->Select(kFP_MCHIS);
return c;
}
void TFitEditor::DoAdvancedOptions()
{
new TAdvancedGraphicsDialog( fClient->GetRoot(), GetMainFrame());
}
void TFitEditor::DoEmptyBinsAllWeights1()
{
if (fEmptyBinsWghts1->GetState() == kButtonDown)
if (fAllWeights1->GetState() == kButtonDown)
fAllWeights1->SetState(kButtonUp, kTRUE);
}
void TFitEditor::DoUseFuncRange()
{
if ( fUseRange->GetState() == kButtonDown ) {
if (fNone->GetState() == kButtonDown || fNone->GetState() == kButtonDisabled) {
TF1* tmpTF1 = FindFunction();
if ( !tmpTF1 ) {
if (GetFitObjectListOfFunctions()) {
TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
tmpTF1 = (TF1*) GetFitObjectListOfFunctions()->FindObject( te->GetTitle() );
}
}
if ( tmpTF1 ) {
Double_t xmin, ymin, zmin, xmax, ymax, zmax;
tmpTF1->GetRange(xmin, ymin, zmin, xmax, ymax, zmax);
if ( fType != kObjectTree ) {
fSliderXMin->SetNumber( xmin );
fSliderXMax->SetNumber( xmax );
DoNumericSliderXChanged();
if ( fDim > 1 ) {
fSliderYMin->SetNumber( ymin );
fSliderYMax->SetNumber( ymax );
DoNumericSliderYChanged();
}
}
}
}
fUseRange->SetState(kButtonDown);
}
}
void TFitEditor::DoAllWeights1()
{
if (fAllWeights1->GetState() == kButtonDown)
if (fEmptyBinsWghts1->GetState() == kButtonDown)
fEmptyBinsWghts1->SetState(kButtonUp, kTRUE);
}
void TFitEditor::DoClose()
{
Hide();
}
void TFitEditor::DoUpdate()
{
GetFunctionsFromSystem();
FillDataSetList();
}
void TFitEditor::DoFit()
{
if (!fFitObject) return;
if ( fNone->GetState() != kButtonDisabled && CheckFunctionString(fEnteredFunc->GetText()) )
{
new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
"Error...", "Verify the entered function string!",
kMBIconStop,kMBOk, 0);
return;
}
fFitButton->SetState(kButtonEngaged);
if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kWatch);
gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
TVirtualPad *save = 0;
if ( fParentPad ) {
fParentPad->Disconnect("RangeAxisChanged()");
save = gPad;
gPad = fParentPad;
fParentPad->cd();
if (fParentPad->GetCanvas())
fParentPad->GetCanvas()->SetCursor(kWatch);
}
ROOT::Fit::DataRange drange;
GetRanges(drange);
static TF1 *fitFunc = 0;
if ( fitFunc )
delete fitFunc;
fitFunc = GetFitFunction();
if (!fitFunc) {
Error("DoFit","This should have never happend, the fitfunc pointer is NULL! - Please Report" );
return;
}
SetParameters(fFuncPars, fitFunc);
ROOT::Math::MinimizerOptions mopts;
Foption_t fitOpts;
TString strDrawOpts;
RetrieveOptions(fitOpts, strDrawOpts, mopts, fitFunc->GetNpar());
switch (fType) {
case kObjectHisto: {
TH1 *hist = dynamic_cast<TH1*>(fFitObject);
if (hist)
ROOT::Fit::FitObject(hist, fitFunc, fitOpts, mopts, strDrawOpts, drange);
break;
}
case kObjectGraph: {
TGraph *gr = dynamic_cast<TGraph*>(fFitObject);
if (gr)
FitObject(gr, fitFunc, fitOpts, mopts, strDrawOpts, drange);
break;
}
case kObjectMultiGraph: {
TMultiGraph *mg = dynamic_cast<TMultiGraph*>(fFitObject);
if (mg)
FitObject(mg, fitFunc, fitOpts, mopts, strDrawOpts, drange);
break;
}
case kObjectGraph2D: {
TGraph2D *g2d = dynamic_cast<TGraph2D*>(fFitObject);
if (g2d)
FitObject(g2d, fitFunc, fitOpts, mopts, strDrawOpts, drange);
break;
}
case kObjectHStack: {
break;
}
case kObjectTree: {
TString variables;
TString cuts;
GetTreeVarsAndCuts(fDataSet, variables, cuts);
TTree *tree = dynamic_cast<TTree*>(fFitObject);
if ( !tree ) return;
gROOT->ls();
tree->Draw(variables,cuts,"goff candle");
TTreePlayer * player = (TTreePlayer*) tree->GetPlayer();
if ( !player ) {
Error("DoFit","Player reference is NULL");
return;
}
TSelectorDraw * selector = (TSelectorDraw* ) player->GetSelector();
if ( !selector ) {
Error("DoFit","Selector reference is NULL");
return;
}
unsigned int ndim = player->GetDimension();
if ( ndim == 0 ) {
Error("DoFit","NDIM == 0");
return;
}
std::vector<double *> vlist;
for (unsigned int i = 0; i < ndim; ++i) {
double * v = selector->GetVal(i);
if (v != 0) vlist.push_back(v);
else
std::cerr << "pointer for variable " << i << " is zero" << std::endl;
}
if (vlist.size() != ndim) {
Error("DoFit","Vector is not complete");
return;
}
Long64_t nrows = player->GetSelectedRows();
if ( !nrows ) {
Error("DoFit","NROWS == 0");
return;
}
ROOT::Fit::UnBinData * fitdata = new ROOT::Fit::UnBinData(nrows, ndim, vlist.begin());
for ( int i = 0; i < std::min(int(fitdata->Size()),10); ++i) {
for (unsigned int j = 0; j < ndim; ++j) {
printf(" x_%d [%d] = %f \n", j, i,*(fitdata->Coords(i)+j) );
}
printf("\n");
}
Foption_t fitOption;
ROOT::Math::MinimizerOptions minOption;
fitOption.Verbose=1;
ROOT::Fit::UnBinFit(fitdata, fitFunc, fitOption, minOption);
break;
}
}
if (fDrawSame->GetState() == kButtonDown && fitFunc)
fitFunc->Draw("same");
GetParameters(fFuncPars,fitFunc);
TF1* tmpTF1 = static_cast<TF1*>( copyTF1(fitFunc) );
ostringstream name;
name << "PrevFit-" << fPrevFit.size() + 1;
if ( strcmp(tmpTF1->GetName(), "PrevFitTMP") != 0 )
name << "-" << tmpTF1->GetName();
tmpTF1->SetName(name.str().c_str());
fPrevFit.insert(FitFuncMap_t::value_type(fFitObject, tmpTF1));
fSystemFuncs.push_back( copyTF1(tmpTF1) );
float xmin, xmax, ymin, ymax, zmin, zmax;
if ( fParentPad ) {
fParentPad->Modified();
if ( fType != kObjectTree ) fSliderX->GetPosition(xmin, xmax);
if ( fDim > 1 ) fSliderY->GetPosition(ymin, ymax);
if ( fDim > 2 ) fSliderZ->GetPosition(zmin, zmax);
fParentPad->Update();
}
fParentPad = gPad;
UpdateGUI();
if ( fParentPad ) {
if ( fType != kObjectTree ) { fSliderX->SetPosition(xmin, xmax); DoSliderXMoved(); }
if ( fType != kObjectTree && fDim > 1 ) { fSliderY->SetPosition(ymin, ymax); DoSliderYMoved(); }
if ( fType != kObjectTree && fDim > 2 ) { fSliderZ->SetPosition(zmin, zmax); DoSliderZMoved(); }
if (fParentPad->GetCanvas())
fParentPad->GetCanvas()->SetCursor(kPointer);
fParentPad->Connect("RangeAxisChanged()", "TFitEditor", this, "UpdateGUI()");
if (save) gPad = save;
if (fSetParam->GetState() == kButtonDisabled &&
fLinearFit->GetState() == kButtonUp)
fSetParam->SetState(kButtonUp);
}
if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kPointer);
gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
fFitButton->SetState(kButtonUp);
if ( !fTypeFit->FindEntry("Prev. Fit") )
fTypeFit->InsertEntry("Prev. Fit",kFP_PREVFIT, kFP_UFUNC);
fDrawAdvanced->SetState(kButtonUp);
}
Int_t TFitEditor::CheckFunctionString(const char *fname)
{
Int_t rvalue = 0;
if ( fDim == 1 || fDim == 0 ) {
TF1 form("tmpCheck", fname);
rvalue = form.Compile();
} else if ( fDim == 2 ) {
TF2 form("tmpCheck", fname);
rvalue = form.Compile();
} else if ( fDim == 3 ) {
TF3 form("tmpCheck", fname);
rvalue = form.Compile();
}
return rvalue;
}
void TFitEditor::DoAddition(Bool_t on)
{
static Bool_t first = kFALSE;
TString s = fEnteredFunc->GetText();
if (on) {
if (!first) {
fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
s += "(0)";
fEnteredFunc->SetText(s.Data());
first = kTRUE;
((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
}
} else {
first = kFALSE;
}
}
void TFitEditor::DoDataSet(Int_t selected)
{
if ( selected == kFP_NOSEL ) {
DoNoSelection();
return;
}
TGTextLBEntry* textEntry = static_cast<TGTextLBEntry*>(fDataSet->GetListBox()->GetEntry(selected));
if (!textEntry) return;
TString textEntryStr = textEntry->GetText()->GetString();
TString name = textEntry->GetText()->GetString()+textEntry->GetText()->First(':')+2;
TString className = textEntryStr(0,textEntry->GetText()->First(':'));
TObject* objSelected(0);
if ( className == "TTree" ) {
TString lookStr;
if ( name.First(' ') == kNPOS )
lookStr = name;
else
lookStr = name(0, name.First(' '));
objSelected = gROOT->FindObject(lookStr);
} else {
objSelected = gROOT->FindObject(name);
}
if ( !objSelected )
{
return;
}
if ( objSelected->InheritsFrom(TTree::Class()) &&
name.First(' ') == kNPOS ) {
char variables[256] = {0}; char cuts[256] = {0};
strlcpy(variables, "Sin input!", 256);
new TTreeInput( fClient->GetRoot(), GetMainFrame(), variables, cuts );
if ( strcmp ( variables, "" ) == 0 ) {
DoNoSelection();
return;
}
ProcessTreeInput(objSelected, selected, variables, cuts);
}
TPad* currentPad = NULL;
bool found = false;
queue<TPad*> stPad;
TIter padIter( gROOT->GetListOfCanvases() );
while ( TObject* canvas = static_cast<TObject*>(padIter() ) ) {
if ( dynamic_cast<TPad*>(canvas) )
stPad.push(dynamic_cast<TPad*>(canvas));
}
while ( !stPad.empty() && !found ) {
currentPad = stPad.front();
stPad.pop();
TIter elemIter( currentPad->GetListOfPrimitives() );
while ( TObject* elem = static_cast<TObject*>(elemIter() ) ) {
if ( elem == objSelected ) {
found = true;
break;
} else if ( dynamic_cast<TPad*>(elem) )
stPad.push( dynamic_cast<TPad*>(elem) );
}
}
SetFitObject( found?currentPad:NULL, objSelected, kButton1Down);
}
void TFitEditor::ProcessTreeInput(TObject* objSelected, Int_t selected, TString variables, TString cuts)
{
TString entryName = (objSelected)->ClassName(); entryName.Append("::"); entryName.Append((objSelected)->GetName());
entryName.Append(" (\""); entryName.Append(variables); entryName.Append("\", \"");
entryName.Append(cuts); entryName.Append("\")");
Int_t newid = fDataSet->GetNumberOfEntries() + kFP_NOSEL;
fDataSet->InsertEntry(entryName, newid, selected );
fDataSet->Select(newid);
}
void TFitEditor::DoFunction(Int_t selected)
{
TGTextLBEntry *te = (TGTextLBEntry *)fFuncList->GetSelectedEntry();
bool editable = false;
if (fNone->GetState() == kButtonDown || fNone->GetState() == kButtonDisabled) {
TF1* tmpTF1 = FindFunction();
if ( !tmpTF1 ) {
if (GetFitObjectListOfFunctions())
tmpTF1 = (TF1*) GetFitObjectListOfFunctions()->FindObject( te->GetTitle() );
}
if ( tmpTF1 && strcmp(tmpTF1->GetExpFormula(), "") )
{
editable = kTRUE;
fEnteredFunc->SetText(tmpTF1->GetExpFormula());
}
else
{
if ( selected <= kFP_USER )
editable = kTRUE;
else
editable = kFALSE;
fEnteredFunc->SetText(te->GetTitle());
}
SetEditable(editable);
} else if (fAdd->GetState() == kButtonDown) {
Int_t np = 0;
TString s = "";
if (!strcmp(fEnteredFunc->GetText(), "")) {
fEnteredFunc->SetText(te->GetTitle());
} else {
s = fEnteredFunc->GetTitle();
TFormula tmp("tmp", fEnteredFunc->GetText());
np = tmp.GetNpar();
}
if (np)
s += TString::Format("+%s(%d)", te->GetTitle(), np);
else
s += TString::Format("%s(%d)", te->GetTitle(), np);
fEnteredFunc->SetText(s.Data());
editable = true;
}
TString tmpStr = fEnteredFunc->GetText();
if (tmpStr.Contains("pol") || tmpStr.Contains("++")) {
fLinearFit->SetState(kButtonDown, kTRUE);
} else {
fLinearFit->SetState(kButtonUp, kTRUE);
}
fEnteredFunc->SelectAll();
fSelLabel->SetText(tmpStr.Sizeof()>30?tmpStr(0,30)+"...":tmpStr);
((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
TF1* fitFunc = GetFitFunction();
if ( fitFunc && (unsigned int) fitFunc->GetNpar() != fFuncPars.size() )
fFuncPars.clear();
if ( fitFunc ) delete fitFunc;
}
void TFitEditor::DoEnteredFunction()
{
if (!strcmp(fEnteredFunc->GetText(), "")) return;
Int_t ok = CheckFunctionString(fEnteredFunc->GetText());
if (ok != 0) {
new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
"Error...", "Verify the entered function string!",
kMBIconStop,kMBOk, 0);
return;
}
TString s = fEnteredFunc->GetText();
fSelLabel->SetText(s.Sizeof()>30?s(0,30)+"...":s);
((TGCompositeFrame *)fSelLabel->GetParent())->Layout();
}
void TFitEditor::DoLinearFit()
{
if (fLinearFit->GetState() == kButtonDown) {
fBestErrors->SetState(kButtonDisabled);
fImproveResults->SetState(kButtonDisabled);
fEnableRobust->SetState(kButtonUp);
} else {
fBestErrors->SetState(kButtonUp);
fImproveResults->SetState(kButtonUp);
fEnableRobust->SetState(kButtonDisabled);
fRobustValue->SetState(kFALSE);
}
}
void TFitEditor::DoNoChi2()
{
}
void TFitEditor::DoRobustFit()
{
if (fEnableRobust->GetState() == kButtonDown)
fRobustValue->SetState(kTRUE);
else
fRobustValue->SetState(kFALSE);
}
void TFitEditor::DoNoStoreDrawing()
{
if (fNoDrawing->GetState() == kButtonUp)
fNoDrawing->SetState(kButtonDown);
}
void TFitEditor::DoPrintOpt(Bool_t on)
{
TGButton *btn = (TGButton *) gTQSender;
Int_t id = btn->WidgetId();
switch (id) {
case kFP_PDEF:
if (on) {
fOptDefault->SetState(kButtonDown);
fOptVerbose->SetState(kButtonUp);
fOptQuiet->SetState(kButtonUp);
}
fStatusBar->SetText("Prn: DEF",4);
break;
case kFP_PVER:
if (on) {
fOptVerbose->SetState(kButtonDown);
fOptDefault->SetState(kButtonUp);
fOptQuiet->SetState(kButtonUp);
}
fStatusBar->SetText("Prn: VER",4);
break;
case kFP_PQET:
if (on) {
fOptQuiet->SetState(kButtonDown);
fOptDefault->SetState(kButtonUp);
fOptVerbose->SetState(kButtonUp);
}
fStatusBar->SetText("Prn: QT",4);
default:
break;
}
}
void TFitEditor::DoReset()
{
if ( fParentPad ) {
fParentPad->Modified();
fParentPad->Update();
}
fEnteredFunc->SetText("gaus");
UpdateGUI();
if (fLinearFit->GetState() == kButtonDown)
fLinearFit->SetState(kButtonUp, kTRUE);
if (fBestErrors->GetState() == kButtonDown)
fBestErrors->SetState(kButtonUp, kFALSE);
if (fUseRange->GetState() == kButtonDown)
fUseRange->SetState(kButtonUp, kFALSE);
if (fAllWeights1->GetState() == kButtonDown)
fAllWeights1->SetState(kButtonUp, kFALSE);
if (fEmptyBinsWghts1->GetState() == kButtonDown)
fEmptyBinsWghts1->SetState(kButtonUp, kFALSE);
if (fImproveResults->GetState() == kButtonDown)
fImproveResults->SetState(kButtonUp, kFALSE);
if (fAdd2FuncList->GetState() == kButtonDown)
fAdd2FuncList->SetState(kButtonUp, kFALSE);
if (fUseGradient->GetState() == kButtonDown)
fUseGradient->SetState(kButtonUp, kFALSE);
if (fEnableRobust->GetState() == kButtonDown)
fEnableRobust->SetState(kButtonUp, kFALSE);
if (fDrawSame->GetState() == kButtonDown)
fDrawSame->SetState(kButtonUp, kFALSE);
if (fNoDrawing->GetState() == kButtonDown)
fNoDrawing->SetState(kButtonUp, kFALSE);
if (fNoStoreDrawing->GetState() == kButtonDown)
fNoStoreDrawing->SetState(kButtonUp, kFALSE);
fNone->SetState(kButtonDown, kTRUE);
fFuncList->Select(1, kTRUE);
if (fLibMinuit->GetState() != kButtonDown)
fLibMinuit->SetState(kButtonDown, kTRUE);
FillMinMethodList();
if (fOptDefault->GetState() != kButtonDown)
fOptDefault->SetState(kButtonDown, kTRUE);
if (fErrorScale->GetNumber() != ROOT::Math::MinimizerOptions::DefaultErrorDef()) {
fErrorScale->SetNumber(ROOT::Math::MinimizerOptions::DefaultErrorDef());
fErrorScale->ReturnPressed();
}
if (fTolerance->GetNumber() != ROOT::Math::MinimizerOptions::DefaultTolerance()) {
fTolerance->SetNumber(ROOT::Math::MinimizerOptions::DefaultTolerance());
fTolerance->ReturnPressed();
}
if (fIterations->GetNumber() != ROOT::Math::MinimizerOptions::DefaultMaxIterations()) {
fIterations->SetIntNumber(ROOT::Math::MinimizerOptions::DefaultMaxIterations());
fIterations->ReturnPressed();
}
}
void TFitEditor::DoSetParameters()
{
TF1* fitFunc = GetFitFunction();
if (!fitFunc) { Error("DoSetParameters","NUll function"); return; }
if (fFuncPars.size() == 0) {
switch (fType) {
case kObjectHisto:
InitParameters( fitFunc, (TH1*)fFitObject) ;
break;
case kObjectGraph:
InitParameters( fitFunc, ((TGraph*)fFitObject));
break;
case kObjectMultiGraph:
InitParameters( fitFunc, ((TMultiGraph*)fFitObject));
break;
case kObjectGraph2D:
InitParameters( fitFunc, ((TGraph2D*)fFitObject));
break;
case kObjectHStack:
case kObjectTree:
default:
break;
}
GetParameters(fFuncPars, fitFunc);
}
else {
SetParameters(fFuncPars, fitFunc);
}
if ( fParentPad ) fParentPad->Disconnect("RangeAxisChanged()");
Int_t ret = 0;
new TFitParametersDialog(gClient->GetDefaultRoot(), GetMainFrame(),
fitFunc, fParentPad, &ret);
GetParameters(fFuncPars, fitFunc);
if ( fParentPad ) fParentPad->Connect("RangeAxisChanged()", "TFitEditor", this, "UpdateGUI()");
if ( fNone->GetState() != kButtonDisabled ) delete fitFunc;
}
void TFitEditor::DoSliderXMoved()
{
if ( !fFitObject ) return;
fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( fSliderX->GetMinPosition() ) ) );
fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderX->GetMaxPosition() ) ) );
fUseRange->SetState(kButtonUp);
DrawSelection();
}
void TFitEditor::DrawSelection(bool restore)
{
static Int_t px1old, py1old, px2old, py2old;
if ( !fParentPad ) return;
if (restore) {
px1old = fParentPad->XtoAbsPixel(fParentPad->GetUxmin());
py1old = fParentPad->YtoAbsPixel(fParentPad->GetUymin());
px2old = fParentPad->XtoAbsPixel(fParentPad->GetUxmax());
py2old = fParentPad->YtoAbsPixel(fParentPad->GetUymax());
return;
}
Int_t px1,py1,px2,py2;
TVirtualPad *save = 0;
save = gPad;
gPad = fParentPad;
gPad->cd();
Double_t xleft = 0;
Double_t xright = 0;
xleft = fXaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5));
xright = fXaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5));
Float_t ymin, ymax;
if ( fDim > 1 )
{
ymin = fYaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5));
ymax = fYaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5));
}
else
{
ymin = gPad->GetUymin();
ymax = gPad->GetUymax();
}
px1 = gPad->XtoAbsPixel(xleft);
py1 = gPad->YtoAbsPixel(ymin);
px2 = gPad->XtoAbsPixel(xright);
py2 = gPad->YtoAbsPixel(ymax);
if (gPad->GetCanvas()) gPad->GetCanvas()->FeedbackMode(kTRUE);
gPad->SetLineWidth(1);
gPad->SetLineColor(2);
gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
px1old = px1;
py1old = py1;
px2old = px2 ;
py2old = py2;
if(save) gPad = save;
}
void TFitEditor::DoNumericSliderXChanged()
{
if ( fSliderXMin->GetNumber() > fSliderXMax->GetNumber() ) {
float xmin, xmax;
fSliderX->GetPosition(xmin, xmax);
fSliderXMin->SetNumber( fXaxis->GetBinLowEdge( static_cast<Int_t>( xmin ) ) );
fSliderXMax->SetNumber( fXaxis->GetBinUpEdge ( static_cast<Int_t>( xmax ) ) );
return;
}
fSliderX->SetPosition(fXaxis->FindBin( fSliderXMin->GetNumber() ),
fXaxis->FindBin( fSliderXMax->GetNumber() ));
fUseRange->SetState(kButtonUp);
DrawSelection();
}
void TFitEditor::DoSliderYMoved()
{
if ( !fFitObject ) return;
fSliderYMin->SetNumber( fYaxis->GetBinLowEdge( static_cast<Int_t>( fSliderY->GetMinPosition() ) ) );
fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( fSliderY->GetMaxPosition() ) ) );
fUseRange->SetState(kButtonUp);
DrawSelection();
}
void TFitEditor::DoNumericSliderYChanged()
{
if ( fSliderYMin->GetNumber() > fSliderYMax->GetNumber() ) {
float ymin, ymax;
fSliderY->GetPosition(ymin, ymax);
fSliderYMin->SetNumber( fYaxis->GetBinLowEdge( static_cast<Int_t>( ymin ) ) );
fSliderYMax->SetNumber( fYaxis->GetBinUpEdge ( static_cast<Int_t>( ymax ) ) );
return;
}
fSliderY->SetPosition( fYaxis->FindBin( fSliderYMin->GetNumber() ),
fYaxis->FindBin( fSliderYMax->GetNumber() ));
fUseRange->SetState(kButtonUp);
DrawSelection();
}
void TFitEditor::DoSliderZMoved()
{
}
void TFitEditor::DoUserDialog()
{
new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
"Info", "Dialog of user method is not implemented yet",
kMBIconAsterisk,kMBOk, 0);
}
void TFitEditor::SetFunction(const char *function)
{
fEnteredFunc->SetText(function);
}
Bool_t TFitEditor::SetObjectType(TObject* obj)
{
Bool_t set = kFALSE;
if (obj->InheritsFrom(TGraph::Class())) {
fType = kObjectGraph;
set = kTRUE;
fDim = 1;
fMethodList->RemoveAll();
fMethodList->AddEntry("Chi-square", kFP_MCHIS);
fMethodList->Select(kFP_MCHIS, kFALSE);
fRobustValue->SetState(kTRUE);
fRobustValue->GetNumberEntry()->SetToolTipText("Set robust value");
} else if (obj->InheritsFrom(TGraph2D::Class())) {
fType = kObjectGraph2D;
set = kTRUE;
fDim = 2;
fMethodList->RemoveAll();
fMethodList->AddEntry("Chi-square", kFP_MCHIS);
fMethodList->Select(kFP_MCHIS, kFALSE);
} else if (obj->InheritsFrom(THStack::Class())) {
fType = kObjectHStack;
set = kTRUE;
TH1 *hist = (TH1 *)((THStack *)obj)->GetHists()->First();
fDim = hist->GetDimension();
fMethodList->RemoveAll();
fMethodList->AddEntry("Chi-square", kFP_MCHIS);
fMethodList->Select(kFP_MCHIS, kFALSE);
} else if (obj->InheritsFrom(TTree::Class())) {
fType = kObjectTree;
set = kTRUE;
TString variables, cuts;
GetTreeVarsAndCuts(fDataSet, variables, cuts);
fDim = 1;
for ( int i = 0; i < variables.Length() && fDim <= 2; ++i )
if ( ':' == variables[i] ) fDim += 1;
if ( fDim > 2 ) fDim = 0;
fMethodList->RemoveAll();
fMethodList->AddEntry("Unbinned Likelihood", kFP_MUBIN);
fMethodList->Select(kFP_MUBIN, kFALSE);
} else if (obj->InheritsFrom(TH1::Class())){
fType = kObjectHisto;
set = kTRUE;
fDim = ((TH1*)obj)->GetDimension();
fMethodList->RemoveAll();
fMethodList->AddEntry("Chi-square", kFP_MCHIS);
fMethodList->AddEntry("Binned Likelihood", kFP_MBINL);
fMethodList->Select(kFP_MCHIS, kFALSE);
} else if (obj->InheritsFrom(TMultiGraph::Class())) {
fType = kObjectMultiGraph;
set = kTRUE;
fDim = 1;
fMethodList->RemoveAll();
fMethodList->AddEntry("Chi-square", kFP_MCHIS);
fMethodList->Select(kFP_MCHIS, kFALSE);
fRobustValue->SetState(kTRUE);
fRobustValue->GetNumberEntry()->SetToolTipText("Set robust value");
}
if ( fDim < 2 || fType == kObjectTree )
fGeneral->HideFrame(fSliderYParent);
else
fGeneral->ShowFrame(fSliderYParent);
if ( fDim < 1 || fType == kObjectTree )
fGeneral->HideFrame(fSliderXParent);
else
fGeneral->ShowFrame(fSliderXParent);
if ( fDim == 1 ) {
if ( !fTypeFit->FindEntry("Predef-1D") )
fTypeFit->InsertEntry("Predef-1D", kFP_PRED1D, kFP_PREVFIT);
} else {
if ( fTypeFit->FindEntry("Predef-1D") )
fTypeFit->RemoveEntry(kFP_PRED1D);
}
if ( fDim == 2 ) {
if ( !fTypeFit->FindEntry("Predef-2D") )
fTypeFit->InsertEntry("Predef-2D", kFP_PRED2D, kFP_PREVFIT);
} else {
if ( fTypeFit->FindEntry("Predef-2D") )
fTypeFit->RemoveEntry(kFP_PRED2D);
}
return set;
}
void TFitEditor::ShowObjectName(TObject* obj)
{
TString name;
bool isTree = false;
if (obj) {
name = obj->ClassName();
name.Append("::");
name.Append(obj->GetName());
isTree = strcmp(obj->ClassName(), "TTree") == 0;
} else {
name = "No object selected";
}
fStatusBar->SetText(name.Data(),0);
TGTextLBEntry* selectedEntry = static_cast<TGTextLBEntry*> ( fDataSet->GetSelectedEntry());
if ( selectedEntry ) {
TString selectedName = selectedEntry->GetText()->GetString();
if ( isTree )
selectedName = selectedName(0, selectedName.First(' '));
if ( name.CompareTo(selectedName) == 0 ) {
Layout();
return;
}
}
Int_t entryId = kFP_NOSEL+1;
bool found = false;
while ( TGTextLBEntry* entry = static_cast<TGTextLBEntry*>
( fDataSet->GetListBox()->GetEntry(entryId)) ) {
TString compareName = entry->GetText()->GetString();
if ( isTree )
compareName = compareName(0, compareName.First(' '));
if ( name.CompareTo(compareName) == 0 ) {
fDataSet->Select(entryId, false);
found = true;
break;
}
entryId += 1;
}
if ( !found ) {
fDataSet->AddEntry(name.Data(), entryId);
fDataSet->Select(entryId, kTRUE);
}
Layout();
}
Option_t *TFitEditor::GetDrawOption() const
{
if (!fParentPad) return "";
TListIter next(fParentPad->GetListOfPrimitives());
TObject *obj;
while ((obj = next())) {
if (obj == fFitObject) return next.GetOption();
}
return "";
}
void TFitEditor::DoLibrary(Bool_t on)
{
TGButton *bt = (TGButton *)gTQSender;
Int_t id = bt->WidgetId();
switch (id) {
case kFP_LMIN:
{
if (on) {
fLibMinuit->SetState(kButtonDown);
fLibMinuit2->SetState(kButtonUp);
fLibFumili->SetState(kButtonUp);
if ( fLibGSL->GetState() != kButtonDisabled )
fLibGSL->SetState(kButtonUp);
if ( fLibGenetics->GetState() != kButtonDisabled )
fLibGenetics->SetState(kButtonUp);
fStatusBar->SetText("LIB Minuit", 1);
}
}
break;
case kFP_LMIN2:
{
if (on) {
fLibMinuit->SetState(kButtonUp);
fLibMinuit2->SetState(kButtonDown);
fLibFumili->SetState(kButtonUp);
if ( fLibGSL->GetState() != kButtonDisabled )
fLibGSL->SetState(kButtonUp);
if ( fLibGenetics->GetState() != kButtonDisabled )
fLibGenetics->SetState(kButtonUp);
fStatusBar->SetText("LIB Minuit2", 1);
}
}
break;
case kFP_LFUM:
{
if (on) {
fLibMinuit->SetState(kButtonUp);
fLibMinuit2->SetState(kButtonUp);
fLibFumili->SetState(kButtonDown);
if ( fLibGSL->GetState() != kButtonDisabled )
fLibGSL->SetState(kButtonUp);
if ( fLibGenetics->GetState() != kButtonDisabled )
fLibGenetics->SetState(kButtonUp);
fStatusBar->SetText("LIB Fumili", 1);
}
}
break;
case kFP_LGSL:
{
if (on) {
fLibMinuit->SetState(kButtonUp);
fLibMinuit2->SetState(kButtonUp);
fLibFumili->SetState(kButtonUp);
if ( fLibGSL->GetState() != kButtonDisabled )
fLibGSL->SetState(kButtonDown);
if ( fLibGenetics->GetState() != kButtonDisabled )
fLibGenetics->SetState(kButtonUp);
fStatusBar->SetText("LIB GSL", 1);
}
}
break;
case kFP_LGAS:
{
if (on) {
fLibMinuit->SetState(kButtonUp);
fLibMinuit2->SetState(kButtonUp);
fLibFumili->SetState(kButtonUp);
if ( fLibGSL->GetState() != kButtonDisabled )
fLibGSL->SetState(kButtonUp);
if ( fLibGenetics->GetState() != kButtonDisabled )
fLibGenetics->SetState(kButtonDown);
fStatusBar->SetText("LIB Genetics", 1);
}
}
default:
break;
}
FillMinMethodList();
}
void TFitEditor::DoMinMethod(Int_t )
{
if ( fMinMethodList->GetSelected() == kFP_MIGRAD )
fStatusBar->SetText("MIGRAD",2);
else if ( fMinMethodList->GetSelected() == kFP_FUMILI)
fStatusBar->SetText("FUMILI",2);
else if ( fMinMethodList->GetSelected() == kFP_SIMPLX )
fStatusBar->SetText("SIMPLEX",2);
else if ( fMinMethodList->GetSelected() == kFP_SCAN )
fStatusBar->SetText("SCAN",2);
else if ( fMinMethodList->GetSelected() == kFP_COMBINATION )
fStatusBar->SetText("Combination",2);
else if ( fMinMethodList->GetSelected() == kFP_GSLFR )
fStatusBar->SetText("CONJFR",2);
else if ( fMinMethodList->GetSelected() == kFP_GSLPR )
fStatusBar->SetText("CONJPR",2);
else if ( fMinMethodList->GetSelected() == kFP_BFGS )
fStatusBar->SetText("BFGS",2);
else if ( fMinMethodList->GetSelected() == kFP_BFGS2 )
fStatusBar->SetText("BFGS2",2);
else if ( fMinMethodList->GetSelected() == kFP_GSLLM )
fStatusBar->SetText("GSLLM",2);
else if ( fMinMethodList->GetSelected() == kFP_GSLSA)
fStatusBar->SetText("SimAn",2);
else if ( fMinMethodList->GetSelected() == kFP_TMVAGA )
fStatusBar->SetText("TMVAGA",2);
else if ( fMinMethodList->GetSelected() == kFP_GALIB )
fStatusBar->SetText("GALIB",2);
}
void TFitEditor::DoMaxIterations()
{
Long_t itr = fIterations->GetIntNumber();
fStatusBar->SetText(Form("Itr: %ld",itr),2);
}
void TFitEditor::MakeTitle(TGCompositeFrame *parent, const char *title)
{
TGCompositeFrame *ht = new TGCompositeFrame(parent, 350, 10,
kFixedWidth | kHorizontalFrame);
ht->AddFrame(new TGLabel(ht, title),
new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
ht->AddFrame(new TGHorizontal3DLine(ht),
new TGLayoutHints(kLHintsExpandX | kLHintsCenterY, 5, 5, 2, 2));
parent->AddFrame(ht, new TGLayoutHints(kLHintsTop, 5, 0, 5, 0));
}
TF1* TFitEditor::HasFitFunction()
{
TList *lf = GetFitObjectListOfFunctions();
TF1* func = 0;
if ( lf ) {
if ( !fTypeFit->FindEntry("Prev. Fit") )
fTypeFit->InsertEntry("Prev. Fit",kFP_PREVFIT, kFP_UFUNC);
TObject *obj2;
TIter next(lf, kIterForward);
while ((obj2 = next())) {
if (obj2->InheritsFrom(TF1::Class())) {
func = (TF1 *)obj2;
fPrevFitIter it;
for ( it = fPrevFit.begin(); it != fPrevFit.end(); ++it) {
if ( it->first != fFitObject ) continue;
if ( strcmp( func->GetName(), it->second->GetName() ) == 0 )
break;
if ( strcmp( func->GetName(), "PrevFitTMP" ) == 0 )
break;
}
if ( it == fPrevFit.end() ) {
fPrevFit.insert( FitFuncMap_t::value_type( fFitObject, static_cast<TF1*>( copyTF1( func ) ) ) );
}
}
}
fTypeFit->Select(kFP_PREVFIT);
FillFunctionList();
fDrawAdvanced->SetState(kButtonUp);
} else {
fTypeFit->Select(kFP_UFUNC);
FillFunctionList();
}
fDrawAdvanced->SetState(kButtonDisabled);
return func;
}
void TFitEditor::RetrieveOptions(Foption_t& fitOpts, TString& drawOpts, ROOT::Math::MinimizerOptions& minOpts, Int_t npar)
{
drawOpts = "";
fitOpts.Range = (fUseRange->GetState() == kButtonDown);
fitOpts.Integral = (fIntegral->GetState() == kButtonDown);
fitOpts.More = (fImproveResults->GetState() == kButtonDown);
fitOpts.Errors = (fBestErrors->GetState() == kButtonDown);
fitOpts.Like = (fMethodList->GetSelected() != kFP_MCHIS);
if (fEmptyBinsWghts1->GetState() == kButtonDown)
fitOpts.W1 = 2;
else if (fAllWeights1->GetState() == kButtonDown)
fitOpts.W1 = 1;
TString tmpStr = fEnteredFunc->GetText();
if ( !(fLinearFit->GetState() == kButtonDown) &&
(tmpStr.Contains("pol") || tmpStr.Contains("++")) )
fitOpts.Minuit = 1;
if ( (int) fFuncPars.size() == npar )
for ( Int_t i = 0; i < npar; ++i )
if ( fFuncPars[i][PAR_MIN] != fFuncPars[i][PAR_MAX] )
{
fitOpts.Bound = 1;
break;
}
fitOpts.Nostore = (fNoStoreDrawing->GetState() == kButtonDown);
fitOpts.Nograph = (fNoDrawing->GetState() == kButtonDown);
fitOpts.Plus = (fAdd2FuncList->GetState() == kButtonDown);
fitOpts.Gradient = (fUseGradient->GetState() == kButtonDown);
fitOpts.Quiet = ( fOptQuiet->GetState() == kButtonDown );
fitOpts.Verbose = ( fOptVerbose->GetState() == kButtonDown );
if ( !(fType != kObjectGraph) && (fEnableRobust->GetState() == kButtonDown) )
{
fitOpts.Robust = 1;
fitOpts.hRobust = fRobustValue->GetNumber();
}
drawOpts = GetDrawOption();
if ( fLibMinuit->GetState() == kButtonDown )
minOpts.SetMinimizerType ( "Minuit");
else if ( fLibMinuit2->GetState() == kButtonDown)
minOpts.SetMinimizerType ( "Minuit2" );
else if ( fLibFumili->GetState() == kButtonDown )
minOpts.SetMinimizerType ("Fumili" );
else if ( fLibGSL->GetState() == kButtonDown )
minOpts.SetMinimizerType ("GSLMultiMin" );
if ( fMinMethodList->GetSelected() == kFP_MIGRAD )
minOpts.SetMinimizerAlgorithm( "Migrad" );
else if ( fMinMethodList->GetSelected() == kFP_FUMILI)
if ( fLibMinuit2->GetState() == kButtonDown )
minOpts.SetMinimizerAlgorithm( "Fumili2" );
else
minOpts.SetMinimizerAlgorithm( "Fumili" );
else if ( fMinMethodList->GetSelected() == kFP_SIMPLX )
minOpts.SetMinimizerAlgorithm( "Simplex" );
else if ( fMinMethodList->GetSelected() == kFP_SCAN )
minOpts.SetMinimizerAlgorithm( "Scan" );
else if ( fMinMethodList->GetSelected() == kFP_COMBINATION )
minOpts.SetMinimizerAlgorithm( "Minimize" );
else if ( fMinMethodList->GetSelected() == kFP_GSLFR )
minOpts.SetMinimizerAlgorithm( "conjugatefr" );
else if ( fMinMethodList->GetSelected() == kFP_GSLPR )
minOpts.SetMinimizerAlgorithm( "conjugatepr" );
else if ( fMinMethodList->GetSelected() == kFP_BFGS )
minOpts.SetMinimizerAlgorithm( "bfgs" );
else if ( fMinMethodList->GetSelected() == kFP_BFGS2 )
minOpts.SetMinimizerAlgorithm( "bfgs2" );
else if ( fMinMethodList->GetSelected() == kFP_GSLLM ) {
minOpts.SetMinimizerType ("GSLMultiFit" );
minOpts.SetMinimizerAlgorithm( "" );
} else if ( fMinMethodList->GetSelected() == kFP_GSLSA) {
minOpts.SetMinimizerType ("GSLSimAn" );
minOpts.SetMinimizerAlgorithm( "" );
} else if ( fMinMethodList->GetSelected() == kFP_TMVAGA) {
minOpts.SetMinimizerType ("Geneti2c" );
minOpts.SetMinimizerAlgorithm( "" );
} else if ( fMinMethodList->GetSelected() == kFP_GALIB) {
minOpts.SetMinimizerType ("GAlibMin" );
minOpts.SetMinimizerAlgorithm( "" );
}
minOpts.SetErrorDef ( fErrorScale->GetNumber() );
minOpts.SetTolerance( fTolerance->GetNumber() );
minOpts.SetMaxIterations(fIterations->GetIntNumber());
minOpts.SetMaxFunctionCalls(fIterations->GetIntNumber());
}
void TFitEditor::SetEditable(Bool_t state)
{
if ( state )
{
fEnteredFunc->SetState(kTRUE);
fAdd->SetState(kButtonUp, kFALSE);
fNone->SetState(kButtonDown, kFALSE);
} else {
fEnteredFunc->SetState(kFALSE);
fAdd->SetState(kButtonDisabled, kFALSE);
fNone->SetState(kButtonDisabled, kFALSE);
}
}
void TFitEditor::GetRanges(ROOT::Fit::DataRange& drange)
{
if ( fType == kObjectTree ) return;
if ( fType != kObjectTree ) {
Int_t ixmin = (Int_t)(fSliderX->GetMinPosition());
Int_t ixmax = (Int_t)(fSliderX->GetMaxPosition());
Double_t xmin = fXaxis->GetBinLowEdge(ixmin);
Double_t xmax = fXaxis->GetBinUpEdge(ixmax);
drange.AddRange(0,xmin, xmax);
}
if ( fDim > 1 ) {
assert(fYaxis);
Int_t iymin = (Int_t)(fSliderY->GetMinPosition());
Int_t iymax = (Int_t)(fSliderY->GetMaxPosition());
Double_t ymin = fYaxis->GetBinLowEdge(iymin);
Double_t ymax = fYaxis->GetBinUpEdge(iymax);
drange.AddRange(1,ymin, ymax);
}
if ( fDim > 2 ) {
assert(fZaxis);
Int_t izmin = (Int_t)(fSliderZ->GetMinPosition());
Int_t izmax = (Int_t)(fSliderZ->GetMaxPosition());
Double_t zmin = fZaxis->GetBinLowEdge(izmin);
Double_t zmax = fZaxis->GetBinUpEdge(izmax);
drange.AddRange(2,zmin, zmax);
}
}
TList* TFitEditor::GetFitObjectListOfFunctions()
{
TList *listOfFunctions = 0;
if ( fFitObject ) {
switch (fType) {
case kObjectHisto:
listOfFunctions = ((TH1 *)fFitObject)->GetListOfFunctions();
break;
case kObjectGraph:
listOfFunctions = ((TGraph *)fFitObject)->GetListOfFunctions();
break;
case kObjectMultiGraph:
listOfFunctions = ((TMultiGraph *)fFitObject)->GetListOfFunctions();
break;
case kObjectGraph2D:
listOfFunctions = ((TGraph2D *)fFitObject)->GetListOfFunctions();
break;
case kObjectHStack:
case kObjectTree:
default:
break;
}
}
return listOfFunctions;
}
void TFitEditor::GetFunctionsFromSystem()
{
for ( fSystemFuncIter it = fSystemFuncs.begin();
it != fSystemFuncs.end();
++it ) {
delete (*it);
}
fSystemFuncs.clear();
const unsigned int nfuncs = 16;
const char* fnames[nfuncs] = { "gaus" , "gausn", "expo", "landau",
"landaun", "pol0", "pol1", "pol2",
"pol3", "pol4", "pol5", "pol6",
"pol7", "pol8", "pol9", "user"
};
TIter functionsIter(gROOT->GetListOfFunctions());
TObject* obj;
while( ( obj = (TObject*) functionsIter() ) ) {
if ( TF1* func = dynamic_cast<TF1*>(obj) ) {
bool addFunction = true;
for ( unsigned int i = 0; i < nfuncs; ++i ) {
if ( strcmp( func->GetName(), fnames[i] ) == 0 ) {
addFunction = false;
break;
}
}
if ( addFunction )
fSystemFuncs.push_back( copyTF1(func) );
}
}
}
TList* TFitEditor::GetListOfFittingFunctions(TObject* obj)
{
if (!obj) obj = fFitObject;
TList *retList = new TList();
std::pair<fPrevFitIter, fPrevFitIter> look = fPrevFit.equal_range(obj);
for ( fPrevFitIter it = look.first; it != look.second; ++it ) {
retList->Add(it->second);
}
return retList;
}
TF1* TFitEditor::GetFitFunction()
{
TF1 *fitFunc = 0;
if ( fNone->GetState() == kButtonDisabled )
{
TF1* tmpF1 = FindFunction();
if ( tmpF1 == 0 )
{
new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
"Error...", "Verify the entered function string!",
kMBIconStop,kMBOk, 0);
return 0;
}
fitFunc = (TF1*)tmpF1->IsA()->New();
tmpF1->Copy(*fitFunc);
if ( int(fFuncPars.size()) != tmpF1->GetNpar() )
{
fitFunc->SetParameters(tmpF1->GetParameters());
GetParameters(fFuncPars, fitFunc);
} else {
SetParameters(fFuncPars, fitFunc);
}
}
if ( fitFunc == 0 )
{
ROOT::Fit::DataRange drange;
GetRanges(drange);
double xmin, xmax, ymin, ymax, zmin, zmax;
drange.GetRange(xmin, xmax, ymin, ymax, zmin, zmax);
if ( fDim == 1 || fDim == 0 ) {
fitFunc = new TF1("PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax );
}
else if ( fDim == 2 ) {
fitFunc = new TF2("PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax, ymin, ymax );
}
else if ( fDim == 3 ) {
fitFunc = new TF3("PrevFitTMP",fEnteredFunc->GetText(), xmin, xmax, ymin, ymax, zmin, zmax );
}
if ( fNone->GetState() != kButtonDisabled )
{
TF1* tmpF1 = FindFunction();
if ( tmpF1 != 0 && fitFunc != 0 &&
strcmp(tmpF1->GetExpFormula(), fEnteredFunc->GetText()) == 0 ) {
if ( int(fFuncPars.size()) != tmpF1->GetNpar() )
{
fitFunc->SetParameters(tmpF1->GetParameters());
GetParameters(fFuncPars, fitFunc);
} else
SetParameters(fFuncPars, fitFunc);
}
}
}
return fitFunc;
}