00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "TFitParametersDialog.h"
00021 #include "TF1.h"
00022 #include "TGButton.h"
00023 #include "TGFrame.h"
00024 #include "TGLabel.h"
00025 #include "TGLayout.h"
00026 #include "TGTextEntry.h"
00027 #include "TGMsgBox.h"
00028 #include "TGNumberEntry.h"
00029 #include "TGTripleSlider.h"
00030 #include "TVirtualPad.h"
00031
00032 #include <limits>
00033
00034
00035 enum EParametersDialogWid {
00036 kNAME,
00037 kFIX = 10,
00038 kBND = 20,
00039 kVAL = 30,
00040 kMIN = 40,
00041 kMAX = 50,
00042 kSLD = 60,
00043 kSTP = 70,
00044 kERR = 80,
00045 kUPDATE = 8888,
00046 kRESET,
00047 kAPPLY,
00048 kOK,
00049 kCANCEL
00050 };
00051
00052 const Double_t kUnlimit = std::numeric_limits<double>::max();
00053
00054 ClassImp(TFitParametersDialog)
00055
00056
00057 TFitParametersDialog::TFitParametersDialog(const TGWindow *p,
00058 const TGWindow *main,
00059 TF1 *func,
00060 TVirtualPad *pad,
00061 Int_t *ret_code) :
00062 TGTransientFrame(p, main, 10, 10, kVerticalFrame),
00063 fFunc (func),
00064 fFpad (pad),
00065 fHasChanges (kFALSE),
00066 fImmediateDraw (kTRUE),
00067 fRetCode (ret_code)
00068
00069 {
00070
00071
00072 SetCleanup(kDeepCleanup);
00073
00074 fFunc->GetRange(fRangexmin, fRangexmax);
00075 fNP = fFunc->GetNpar();
00076 fPmin = new Double_t[fNP];
00077 fPmax = new Double_t[fNP];
00078 fPval = new Double_t[fNP];
00079 fPerr = new Double_t[fNP];
00080 fPstp = new Double_t[fNP];
00081
00082 for (Int_t i = 0; i < fNP; i++) {
00083 fFunc->GetParLimits(i, fPmin[i], fPmax[i]);
00084 fPval[i] = fFunc->GetParameter(i);
00085 fPerr[i] = fFunc->GetParError(i);
00086 if (TMath::Abs(fPval[i]) > 1E-16)
00087 fPstp[i] = 0.3*TMath::Abs(fPval[i]);
00088 else
00089 fPstp[i] = 0.1;
00090 }
00091 fParNam = new TGTextEntry*[fNP];
00092 fParFix = new TGCheckButton*[fNP];
00093 fParBnd = new TGCheckButton*[fNP];
00094 fParVal = new TGNumberEntry*[fNP];
00095 fParMin = new TGNumberEntryField*[fNP];
00096 fParMax = new TGNumberEntryField*[fNP];
00097 fParSld = new TGTripleHSlider*[fNP];
00098 fParStp = new TGNumberEntry*[fNP];
00099 fParErr = new TGNumberEntryField*[fNP];
00100
00101 memset(fParNam, 0, sizeof(TGTextEntry*)*fNP);
00102 memset(fParFix, 0, sizeof(TGCheckButton*)*fNP);
00103 memset(fParBnd, 0, sizeof(TGCheckButton*)*fNP);
00104 memset(fParVal, 0, sizeof(TGNumberEntry*)*fNP);
00105 memset(fParMin, 0, sizeof(TGNumberEntryField*)*fNP);
00106 memset(fParMax, 0, sizeof(TGNumberEntryField*)*fNP);
00107 memset(fParSld, 0, sizeof(TGTripleHSlider*)*fNP);
00108 memset(fParStp, 0, sizeof(TGNumberEntry*)*fNP);
00109 memset(fParErr, 0, sizeof(TGNumberEntryField*)*fNP);
00110
00111 TGCompositeFrame *f1 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame);
00112 AddFrame(f1, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));
00113
00114
00115 fContNam = new TGCompositeFrame(f1, 80, 20, kVerticalFrame | kFixedWidth);
00116 fContNam->AddFrame(new TGLabel(fContNam,"Name"),
00117 new TGLayoutHints(kLHintsTop, 5, 0, 0, 0));
00118 for (Int_t i = 0; i < fNP; i++ ) {
00119 fParNam[i] = new TGTextEntry(fContNam, new TGTextBuffer(80), kNAME+i);
00120 fParNam[i]->SetText(Form("%s", fFunc->GetParName(i)));
00121 fParNam[i]->SetEnabled(kFALSE);
00122 fContNam->AddFrame(fParNam[i],
00123 new TGLayoutHints(kLHintsExpandX, 2, 2, 7, 5));
00124 }
00125 f1->AddFrame(fContNam, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2));
00126
00127
00128 fContFix = new TGCompositeFrame(f1, 20, 20, kVerticalFrame | kFixedWidth);
00129 fContFix->AddFrame(new TGLabel(fContFix,"Fix"),
00130 new TGLayoutHints(kLHintsTop, 2, 0, 0, 0));
00131 for (Int_t i = 0; i < fNP; i++ ) {
00132 fParFix[i] = new TGCheckButton(fContFix, "", kFIX*fNP+i);
00133 fParFix[i]->SetToolTipText(Form("Set %s to fixed", fFunc->GetParName(i)));
00134 fContFix->AddFrame(fParFix[i], new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
00135 5, 5, 10, 7));
00136 if ((fPmin[i] == fPmax[i]) && (fPmin[i] || fPmax[i]))
00137 fParFix[i]->SetState(kButtonDown);
00138 else
00139 fParFix[i]->SetState(kButtonUp);
00140 fParFix[i]->Connect("Toggled(Bool_t)", "TFitParametersDialog", this, "DoParFix(Bool_t)");
00141 }
00142 f1->AddFrame(fContFix, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2));
00143
00144
00145 fContBnd = new TGCompositeFrame(f1, 40, 20, kVerticalFrame | kFixedWidth);
00146 fContBnd->AddFrame(new TGLabel(fContBnd,"Bound"),
00147 new TGLayoutHints(kLHintsTop, 2, 0, 0, 0));
00148 for (Int_t i = 0; i < fNP; i++ ) {
00149 fParBnd[i] = new TGCheckButton(fContBnd, "", kBND*fNP+i);
00150 fParBnd[i]->SetToolTipText(Form("Set bound to %s", fFunc->GetParName(i)));
00151 fContBnd->AddFrame(fParBnd[i], new TGLayoutHints(kLHintsLeft | kLHintsCenterY,
00152 15, 5, 10, 7));
00153 fParBnd[i]->Connect("Toggled(Bool_t)", "TFitParametersDialog", this, "DoParBound(Bool_t)");
00154 if ( ((fPmin[i] != fPmax[i]) && (fPmin[i] || fPmax[i])) || (fParMin[i] < fParMax[i]) )
00155 fParBnd[i]->SetState(kButtonDown, kFALSE);
00156 else
00157 fParBnd[i]->SetState(kButtonUp, kFALSE);
00158 }
00159 f1->AddFrame(fContBnd, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2));
00160
00161
00162 fContVal = new TGCompositeFrame(f1, 100, 20, kVerticalFrame | kFixedWidth);
00163 fContVal->AddFrame(new TGLabel(fContVal,"Value"),
00164 new TGLayoutHints(kLHintsTop, 5, 0, 0, 0));
00165 for (Int_t i = 0; i < fNP; i++ ) {
00166 fParVal[i] = new TGNumberEntry(fContVal, 1.2E-12, 15, kVAL*fNP+i,
00167 TGNumberFormat::kNESReal);
00168 fParVal[i]->SetNumber(fPval[i]);
00169 fParVal[i]->SetFormat(TGNumberFormat::kNESReal, TGNumberFormat::kNEAAnyNumber);
00170 fContVal->AddFrame(fParVal[i], new TGLayoutHints(kLHintsExpandX, 2, 2, 7, 5));
00171 (fParVal[i]->GetNumberEntry())->SetToolTipText(Form("%s", fFunc->GetParName(i)));
00172 (fParVal[i]->GetNumberEntry())->Connect("ReturnPressed()", "TFitParametersDialog",
00173 this, "DoParValue()");
00174 fParVal[i]->Connect("ValueSet(Long_t)", "TFitParametersDialog", this, "DoParValue()");
00175 }
00176 f1->AddFrame(fContVal, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2));
00177
00178
00179 fContMin = new TGCompositeFrame(f1, 100, 20, kVerticalFrame | kFixedWidth);
00180 fContMin->AddFrame(new TGLabel(fContMin,"Min"),
00181 new TGLayoutHints(kLHintsTop, 5, 0, 0, 0));
00182 for (Int_t i = 0; i < fNP; i++ ) {
00183 fParMin[i] = new TGNumberEntryField(fContMin, kMIN*fNP+i, 0.0,
00184 TGNumberFormat::kNESReal,
00185 TGNumberFormat::kNEAAnyNumber);
00186 ((TGTextEntry*)fParMin[i])->SetToolTipText(Form("Lower limit of %s",
00187 fFunc->GetParName(i)));
00188 fContMin->AddFrame(fParMin[i], new TGLayoutHints(kLHintsExpandX, 2, 2, 7, 5));
00189 fParMin[i]->SetNumber(fPmin[i]);
00190 fParMin[i]->Connect("ReturnPressed()", "TFitParametersDialog", this, "DoParMinLimit()");
00191 }
00192 f1->AddFrame(fContMin, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2));
00193
00194
00195 fContSld = new TGCompositeFrame(f1, 120, 20, kVerticalFrame | kFixedWidth);
00196 fContSld->AddFrame(new TGLabel(fContSld,"Set Range"),
00197 new TGLayoutHints(kLHintsTop, 5, 0, 0, 0));
00198 for (Int_t i = 0; i < fNP; i++ ) {
00199 fParSld[i] = new TGTripleHSlider(fContSld, 100, kDoubleScaleBoth, kSLD*fNP+i,
00200 kHorizontalFrame, GetDefaultFrameBackground(),
00201 kFALSE, kFALSE, kFALSE, kFALSE);
00202 fContSld->AddFrame(fParSld[i], new TGLayoutHints(kLHintsExpandX, 2, 2, 5, 5));
00203 fParSld[i]->SetConstrained(kTRUE);
00204 }
00205 f1->AddFrame(fContSld, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2));
00206
00207
00208 fContMax = new TGCompositeFrame(f1, 100, 20, kVerticalFrame | kFixedWidth);
00209 fContMax->AddFrame(new TGLabel(fContMax,"Max"),
00210 new TGLayoutHints(kLHintsTop, 5, 0, 0, 0));
00211 for (Int_t i = 0; i < fNP; i++ ) {
00212 fParMax[i] = new TGNumberEntryField(fContMax, kMAX*fNP+i, 0.0,
00213 TGNumberFormat::kNESReal,
00214 TGNumberFormat::kNEAAnyNumber);
00215 ((TGTextEntry*)fParMax[i])->SetToolTipText(Form("Upper limit of %s",
00216 fFunc->GetParName(i)));
00217 fContMax->AddFrame(fParMax[i], new TGLayoutHints(kLHintsExpandX, 2, 2, 7, 5));
00218 fParMax[i]->SetNumber(fPmax[i]);
00219 fParMax[i]->Connect("ReturnPressed()", "TFitParametersDialog", this, "DoParMaxLimit()");
00220 }
00221 f1->AddFrame(fContMax, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2));
00222
00223
00224 fContStp = new TGCompositeFrame(f1, 100, 20, kVerticalFrame | kFixedWidth);
00225 fContStp->AddFrame(new TGLabel(fContStp,"Step"),
00226 new TGLayoutHints(kLHintsTop, 5, 0, 0, 0));
00227 for (Int_t i = 0; i < fNP; i++ ) {
00228 fParStp[i] = new TGNumberEntry(fContStp, 1.2E-12, 15, kSTP*fNP+i,
00229 TGNumberFormat::kNESReal);
00230 fParStp[i]->SetNumber(fPstp[i]);
00231 fParStp[i]->SetFormat(TGNumberFormat::kNESReal, TGNumberFormat::kNEAAnyNumber);
00232 fContStp->AddFrame(fParStp[i], new TGLayoutHints(kLHintsExpandX, 2, 2, 7, 5));
00233 (fParStp[i]->GetNumberEntry())->SetToolTipText(Form("%s", fFunc->GetParName(i)));
00234 (fParStp[i]->GetNumberEntry())->Connect("ReturnPressed()", "TFitParametersDialog",
00235 this, "DoParStep()");
00236 fParStp[i]->Connect("ValueSet(Long_t)", "TFitParametersDialog", this, "DoParStep()");
00237 }
00238 f1->AddFrame(fContStp, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2));
00239
00240
00241 fContErr = new TGCompositeFrame(f1, 80, 20, kVerticalFrame | kFixedWidth);
00242 fContErr->AddFrame(new TGLabel(fContErr,"Errors"),
00243 new TGLayoutHints(kLHintsTop, 5, 0, 0, 0));
00244 for (Int_t i = 0; i < fNP; i++ ) {
00245 fParErr[i] = new TGNumberEntryField(fContErr, kERR*fNP+i, 0.0,
00246 TGNumberFormat::kNESReal,
00247 TGNumberFormat::kNEAAnyNumber);
00248 ((TGTextEntry*)fParErr[i])->SetToolTipText(Form("Error of %s",
00249 fFunc->GetParName(i)));
00250 fContErr->AddFrame(fParErr[i], new TGLayoutHints(kLHintsExpandX, 2, 2, 7, 5));
00251 fParErr[i]->SetEnabled(kFALSE);
00252 if (fPerr[i])
00253 fParErr[i]->SetNumber(fPerr[i]);
00254 else
00255 ((TGTextEntry *)fParErr[i])->SetText("-");
00256 }
00257 f1->AddFrame(fContErr, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 2));
00258
00259 TGCompositeFrame *f2 = new TGCompositeFrame(this, 270, 20, kHorizontalFrame);
00260 AddFrame(f2, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX));
00261
00262 fUpdate = new TGCheckButton(f2, "&Immediate preview", kUPDATE);
00263 fUpdate->SetToolTipText("Immediate function redrawing");
00264 fUpdate->SetState(kButtonDown);
00265 f2->AddFrame(fUpdate, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 5, 5, 5));
00266 fUpdate->Connect("Toggled(Bool_t)", "TFitParametersDialog", this, "HandleButtons(Bool_t)");
00267
00268 TGCompositeFrame *f3 = new TGCompositeFrame(f2, 270, 20, kHorizontalFrame | kFixedWidth);
00269 f2->AddFrame(f3, new TGLayoutHints(kLHintsRight));
00270
00271 fReset = new TGTextButton(f3, "&Reset", kRESET);
00272 f3->AddFrame(fReset, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX,2,2,5,5));
00273 fReset->SetToolTipText("Reset the parameter settings");
00274 fReset->SetState(kButtonDisabled);
00275 fReset->Connect("Clicked()", "TFitParametersDialog", this, "DoReset()");
00276
00277 fApply = new TGTextButton(f3, "&Apply", kAPPLY);
00278 f3->AddFrame(fApply, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX,2,2,5,5));
00279 fApply->SetState(kButtonDisabled);
00280 fApply->Connect("Clicked()", "TFitParametersDialog", this, "DoApply()");
00281 fApply->SetToolTipText("Apply parameter settings and redraw the function");
00282
00283 fOK = new TGTextButton(f3, "&OK", kOK);
00284 f3->AddFrame(fOK, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX,2,2,5,5));
00285 fOK->SetToolTipText("Apply parameter settings, redraw function and close this dialog");
00286 fOK->Connect("Clicked()", "TFitParametersDialog", this, "DoOK()");
00287
00288 fCancel = new TGTextButton(f3, "&Cancel", kCANCEL);
00289 f3->AddFrame(fCancel, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX,2,2,5,5));
00290 fCancel->SetToolTipText("Close this dialog with no parameter changes");
00291 fCancel->Connect("Clicked()", "TFitParametersDialog", this, "DoCancel()");
00292 *fRetCode = kFPDNoneBounded;
00293
00294 MapSubwindows();
00295 Resize(GetDefaultSize());
00296 MapWindow();
00297 CenterOnParent(kFALSE, kBottomLeft);
00298 SetWindowName(Form("Set Parameters of %s", fFunc->GetTitle()));
00299
00300 for (Int_t i = 0; i < fNP; i++ ) {
00301 if (fParFix[i]->GetState() == kButtonDown) {
00302 fParVal[i]->SetState(kFALSE);
00303 fParMin[i]->SetEnabled(kFALSE);
00304 fParMax[i]->SetEnabled(kFALSE);
00305 fParSld[i]->UnmapWindow();
00306 } else {
00307 if (fPmin[i]*fPmax[i] == 0 && fPmin[i] >= fPmax[i]) {
00308 if (!fPval[i]) {
00309 fParMin[i]->SetNumber(-10);
00310 fParMax[i]->SetNumber(10);
00311 } else {
00312 fParMin[i]->SetNumber(-3*TMath::Abs(fPval[i]));
00313 fParMax[i]->SetNumber(3*TMath::Abs(fPval[i]));
00314 }
00315 }
00316 fParSld[i]->SetRange(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00317 fParSld[i]->SetPosition(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00318 fParSld[i]->SetPointerPosition(fParVal[i]->GetNumber());
00319 fParSld[i]->Connect("PointerPositionChanged()", "TFitParametersDialog",
00320 this, "DoSlider()");
00321 fParSld[i]->Connect("PositionChanged()", "TFitParametersDialog",
00322 this, "DoSlider()");
00323 }
00324 }
00325
00326 gClient->WaitFor(this);
00327 }
00328
00329
00330 TFitParametersDialog::~TFitParametersDialog()
00331 {
00332
00333
00334 DisconnectSlots();
00335 Cleanup();
00336 delete [] fPval;
00337 delete [] fPmin;
00338 delete [] fPmax;
00339 delete [] fPerr;
00340 delete [] fPstp;
00341
00342 delete [] fParNam;
00343 delete [] fParFix;
00344 delete [] fParBnd;
00345 delete [] fParVal;
00346 delete [] fParMin;
00347 delete [] fParMax;
00348 delete [] fParSld;
00349 delete [] fParStp;
00350 delete [] fParErr;
00351 }
00352
00353
00354 void TFitParametersDialog::CloseWindow()
00355 {
00356
00357
00358 if (fHasChanges) {
00359 Int_t ret;
00360 const char *txt;
00361 txt = "Do you want to apply last parameters' setting?";
00362 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
00363 "Parameters Have Been Changed", txt, kMBIconExclamation,
00364 kMBYes | kMBNo | kMBCancel, &ret);
00365 if (ret == kMBYes)
00366 SetParameters();
00367 else if (ret == kMBNo)
00368 DoReset();
00369 else return;
00370 }
00371
00372 DisconnectSlots();
00373 DeleteWindow();
00374 }
00375
00376
00377 void TFitParametersDialog::DoCancel()
00378 {
00379
00380
00381 if (fHasChanges)
00382 DoReset();
00383 for (Int_t i = 0; i < fNP; i++ ) {
00384 if (fParBnd[i]->GetState() == kButtonDown)
00385 *fRetCode = kFPDBounded;
00386 }
00387 CloseWindow();
00388 }
00389
00390
00391 void TFitParametersDialog::DoParBound(Bool_t on)
00392 {
00393
00394
00395 TGButton *bt = (TGButton *) gTQSender;
00396 Int_t id = bt->WidgetId();
00397 fHasChanges = kTRUE;
00398
00399 for (Int_t i = 0; i < fNP; i++ ) {
00400 if (id == kBND*fNP+i) {
00401 if (on) {
00402 if (fParMin[i]->GetNumber() >= fParMax[i]->GetNumber()) {
00403 Int_t ret;
00404 const char *txt;
00405 txt = "'Min' value cannot be bigger or equal to 'Max' - set the limits first!";
00406 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
00407 "Parameter Limits", txt, kMBIconExclamation,kMBOk,&ret);
00408
00409 fParBnd[i]->SetState(kButtonUp, kFALSE);
00410 return;
00411 }
00412 if ((fParVal[i]->GetNumber() < fParMin[i]->GetNumber()) ||
00413 (fParVal[i]->GetNumber() > fParMax[i]->GetNumber())) {
00414 Double_t v = (fParMax[i]->GetNumber()+fParMin[i]->GetNumber())/2.;
00415 fParVal[i]->SetNumber(v);
00416 fFunc->SetParameter(i, v);
00417 fClient->NeedRedraw(fParVal[i]);
00418 }
00419 fParVal[i]->SetLimits(TGNumberFormat::kNELLimitMinMax,
00420 fParMin[i]->GetNumber(),
00421 fParMax[i]->GetNumber());
00422 fClient->NeedRedraw(fParVal[i]);
00423 fFunc->SetParLimits(i, fParMin[i]->GetNumber(),
00424 fParMax[i]->GetNumber());
00425 } else {
00426 fParVal[i]->SetLimits(TGNumberFormat::kNELNoLimits);
00427 fFunc->ReleaseParameter(i);
00428 fFunc->GetParLimits(i, fPmin[i], fPmax[i]);
00429 fPval[i] = fFunc->GetParameter(i);
00430 if (fPmin[i]*fPmax[i] == 0 && fPmin[i] >= fPmax[i]) {
00431 if (!fPval[i]) {
00432 fParMin[i]->SetNumber(-10);
00433 fParMax[i]->SetNumber(10);
00434 } else {
00435 fParMin[i]->SetNumber(-10*TMath::Abs(fPval[i]));
00436 fParMax[i]->SetNumber(10*TMath::Abs(fPval[i]));
00437 }
00438 }
00439 fParSld[i]->SetRange(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00440 fParSld[i]->SetPosition(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00441 fParSld[i]->SetPointerPosition(fPval[i]);
00442 }
00443 }
00444 }
00445 if (fUpdate->GetState() == kButtonDown)
00446 DrawFunction();
00447 else if ((fApply->GetState() == kButtonDisabled) && fHasChanges)
00448 fApply->SetState(kButtonUp);
00449 *fRetCode = kFPDBounded;
00450 }
00451
00452
00453 void TFitParametersDialog::DoParStep()
00454 {
00455
00456
00457 }
00458
00459
00460 void TFitParametersDialog::DoParFix(Bool_t on)
00461 {
00462
00463
00464 fReset->SetState(kButtonUp);
00465
00466 TGButton *bt = (TGButton *) gTQSender;
00467 Int_t id = bt->WidgetId();
00468 fHasChanges = kTRUE;
00469
00470 for (Int_t i = 0; i < fNP; i++ ) {
00471 if (id == kFIX*fNP+i) {
00472 if (on) {
00473
00474 fParBnd[i]->Disconnect("Toggled(Bool_t)");
00475 fParBnd[i]->SetEnabled(kFALSE);
00476 fParBnd[i]->SetToolTipText(Form("DISABLED - %s is fixed", fFunc->GetParName(i)));
00477 if (fParVal[i]->GetNumber() != 0) {
00478 fParMin[i]->SetNumber(fParVal[i]->GetNumber());
00479 fParMin[i]->SetEnabled(kFALSE);
00480 fParMax[i]->SetNumber(fParVal[i]->GetNumber());
00481 fParMax[i]->SetEnabled(kFALSE);
00482 } else {
00483 fParMin[i]->SetNumber(1.);
00484 fParMin[i]->SetEnabled(kFALSE);
00485 fParMax[i]->SetNumber(1.);
00486 fParMax[i]->SetEnabled(kFALSE);
00487 }
00488 fParVal[i]->SetState(kFALSE);
00489 fParStp[i]->SetState(kFALSE);
00490 fParSld[i]->Disconnect("PointerPositionChanged()");
00491 fParSld[i]->Disconnect("PositionChanged()");
00492 fParSld[i]->UnmapWindow();
00493 fFunc->FixParameter(i, fParVal[i]->GetNumber());
00494 } else if (!fParMin[i]->IsEnabled()) {
00495 if (fPmin[i] != fPmax[i]) {
00496 if (fPmin[i])
00497 fParMin[i]->SetNumber(fPmin[i]);
00498 else if (fPerr[i])
00499 fParMin[i]->SetNumber(fPval[i]-3*fPerr[i]);
00500 else if (fPval[i])
00501 fParMin[i]->SetNumber(fPval[i]-0.1*fPval[i]);
00502 else
00503 fParMin[i]->SetNumber(1.0);
00504 if (fPmax[i])
00505 fParMax[i]->SetNumber(fPmax[i]);
00506 else if (fPerr[i])
00507 fParMax[i]->SetNumber(fPval[i]+3*fPerr[i]);
00508 else if (fPval[i])
00509 fParMax[i]->SetNumber(fPval[i]+0.1*fPval[i]);
00510 else
00511 fParMax[i]->SetNumber(1.0);
00512 } else if (fPval[i]) {
00513 fParMin[i]->SetNumber(fPval[i]-0.1*fPval[i]);
00514 fParMax[i]->SetNumber(fPval[i]+0.1*fPval[i]);
00515 } else {
00516 fParMin[i]->SetNumber(1.0);
00517 fParMax[i]->SetNumber(1.0);
00518 }
00519 if (fParMax[i]->GetNumber() < fParMin[i]->GetNumber()){
00520 Double_t temp;
00521 temp = fParMax[i]->GetNumber();
00522 fParMax[i]->SetNumber(fParMin[i]->GetNumber());
00523 fParMin[i]->SetNumber(temp);
00524 }
00525 fParBnd[i]->SetEnabled(kTRUE);
00526 fParBnd[i]->Connect("Toggled(Bool_t)", "TFitParametersDialog",
00527 this, "DoParBound(Bool_t)");
00528 fParBnd[i]->SetState(kButtonUp);
00529 fParMax[i]->SetEnabled(kTRUE);
00530 fParMin[i]->SetEnabled(kTRUE);
00531 fParSld[i]->MapWindow();
00532 fParVal[i]->SetState(kTRUE);
00533 fParStp[i]->SetState(kTRUE);
00534 fParSld[i]->SetRange(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00535 fParSld[i]->SetPosition(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00536 fParSld[i]->SetPointerPosition(fPval[i]);
00537 fParSld[i]->Connect("PointerPositionChanged()", "TFitParametersDialog",
00538 this, "DoSlider()");
00539 fParSld[i]->Connect("PositionChanged()", "TFitParametersDialog",
00540 this, "DoSlider()");
00541 fFunc->SetParLimits(i, fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00542 }
00543 }
00544 }
00545 if (fUpdate->GetState() == kButtonDown)
00546 DrawFunction();
00547 else if ((fApply->GetState() == kButtonDisabled) && fHasChanges)
00548 fApply->SetState(kButtonUp);
00549 }
00550
00551
00552 void TFitParametersDialog::SetParameters()
00553 {
00554
00555 fFunc->SetRange(fRangexmin, fRangexmax);
00556 for (Int_t i = 0; i < fNP; i++ ) {
00557 if (fParFix[i]->GetState() == kButtonDown) {
00558 fFunc->SetParameter(i, fParVal[i]->GetNumber());
00559 fFunc->FixParameter(i, fParVal[i]->GetNumber());
00560 *fRetCode = kFPDBounded;
00561 } else {
00562 if (fParBnd[i]->GetState() == kButtonDown) {
00563 fFunc->SetParameter(i, fParVal[i]->GetNumber());
00564 fFunc->SetParLimits(i, fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00565 *fRetCode = kFPDBounded;
00566 } else {
00567 fFunc->ReleaseParameter(i);
00568 }
00569 }
00570 }
00571 }
00572
00573
00574 void TFitParametersDialog::DoOK()
00575 {
00576
00577
00578 if (fHasChanges)
00579 DrawFunction();
00580
00581 SetParameters();
00582
00583 CloseWindow();
00584 }
00585
00586
00587 void TFitParametersDialog::DoApply()
00588 {
00589
00590
00591 DrawFunction();
00592 fApply->SetState(kButtonDisabled);
00593 if (fReset->GetState() == kButtonDisabled)
00594 fReset->SetState(kButtonUp);
00595 }
00596
00597
00598 void TFitParametersDialog::DoReset()
00599 {
00600
00601
00602 fHasChanges = kTRUE;
00603 Int_t k = fNP;
00604 for (Int_t i = 0; i < fNP; i++) {
00605 if (fParVal[i]->GetNumber() == fPval[i])
00606 k--;
00607 else
00608 break;
00609 }
00610
00611 if (!k) {
00612 if (fReset->GetState() == kButtonUp)
00613 fReset->SetState(kButtonDisabled);
00614 fHasChanges = kFALSE;
00615 return;
00616 }
00617 for (Int_t i = 0; i < fNP; i++) {
00618 fFunc->SetParameter(i, fPval[i]);
00619 fFunc->SetParLimits(i, fPmin[i], fPmax[i]);
00620 fFunc->SetParError(i, fPerr[i]);
00621
00622 if (fPmin[i])
00623 fParMin[i]->SetNumber(fPmin[i]);
00624 else if (fPerr[i])
00625 fParMin[i]->SetNumber(fPval[i]-3*fPerr[i]);
00626 else if (fPval[i])
00627 fParMin[i]->SetNumber(-3*TMath::Abs(fPval[i]));
00628 else
00629 fParMin[i]->SetNumber(1.0);
00630
00631 if (fPmax[i])
00632 fParMax[i]->SetNumber(fPmax[i]);
00633 else if (fPerr[i])
00634 fParMax[i]->SetNumber(fPval[i]+3*fPerr[i]);
00635 else if (fPval[i])
00636 fParMax[i]->SetNumber(3*TMath::Abs(fPval[i]));
00637 else
00638 fParMax[i]->SetNumber(1.0);
00639 if (fParMax[i]->GetNumber() < fParMin[i]->GetNumber()){
00640 Double_t temp;
00641 temp = fParMax[i]->GetNumber();
00642 fParMax[i]->SetNumber(fParMin[i]->GetNumber());
00643 fParMin[i]->SetNumber(temp);
00644 }
00645 if (fParMin[i]->GetNumber() == fParMax[i]->GetNumber()) {
00646 fParVal[i]->SetState(kFALSE);
00647 fParMin[i]->SetEnabled(kFALSE);
00648 fParMax[i]->SetEnabled(kFALSE);
00649 fParStp[i]->SetState(kFALSE);
00650 fParSld[i]->Disconnect("PointerPositionChanged()");
00651 fParSld[i]->Disconnect("PositionChanged()");
00652 fParSld[i]->UnmapWindow();
00653 fParBnd[i]->Disconnect("Toggled(Bool_t)");
00654 fParBnd[i]->SetEnabled(kFALSE);
00655 fFunc->FixParameter(i, fParVal[i]->GetNumber());
00656 fParFix[i]->SetState(kButtonDown);
00657 } else {
00658 fParFix[i]->SetState(kButtonUp);
00659 if (!fParMax[i]->IsEnabled()) {
00660 fParMax[i]->SetEnabled(kTRUE);
00661 fParMin[i]->SetEnabled(kTRUE);
00662 fParVal[i]->SetState(kTRUE);
00663 fParStp[i]->SetState(kTRUE);
00664 fParSld[i]->SetRange(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00665 fParSld[i]->SetPosition(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00666 fParSld[i]->SetPointerPosition(fPval[i]);
00667 fParSld[i]->MapWindow();
00668 fParSld[i]->Connect("PointerPositionChanged()", "TFitParametersDialog",
00669 this, "DoSlider()");
00670 fParSld[i]->Connect("PositionChanged()", "TFitParametersDialog",
00671 this, "DoSlider()");
00672 fParBnd[i]->SetEnabled(kTRUE);
00673 fParBnd[i]->Connect("Toggled(Bool_t)", "TFitParametersDialog",
00674 this, "DoParBound()");
00675 }
00676 }
00677 fParVal[i]->SetNumber(fPval[i]);
00678
00679 fParSld[i]->SetRange(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00680 fParSld[i]->SetPosition(fParMin[i]->GetNumber(), fParMax[i]->GetNumber());
00681 fParSld[i]->SetPointerPosition(fPval[i]);
00682 }
00683
00684 if (fUpdate->GetState() == kButtonDown)
00685 DrawFunction();
00686 else if ((fApply->GetState() == kButtonDisabled) && fHasChanges)
00687 fApply->SetState(kButtonUp);
00688 fHasChanges = kFALSE;
00689 *fRetCode = kFPDBounded;
00690 fReset->SetState(kButtonDisabled);
00691 }
00692
00693
00694 void TFitParametersDialog::DoSlider()
00695 {
00696
00697
00698 TGTripleHSlider *sl = (TGTripleHSlider *) gTQSender;
00699 Int_t id = sl->WidgetId();
00700
00701 fHasChanges = kTRUE;
00702 for (Int_t i = 0; i < fNP; i++ ) {
00703 if (id == kSLD*fNP+i) {
00704 fFunc->SetParameter(i,fParSld[i]->GetPointerPosition());
00705 fFunc->SetParLimits(i,fParSld[i]->GetMinPosition(),
00706 fParSld[i]->GetMaxPosition());
00707 fParMin[i]->SetNumber(fParSld[i]->GetMinPosition());
00708 fParMax[i]->SetNumber(fParSld[i]->GetMaxPosition());
00709 fParVal[i]->SetNumber(fParSld[i]->GetPointerPosition());
00710 }
00711 }
00712 if (fUpdate->GetState() == kButtonDown)
00713 DrawFunction();
00714 else if ((fApply->GetState() == kButtonDisabled) && fHasChanges)
00715 fApply->SetState(kButtonUp);
00716 if (fReset->GetState() == kButtonDisabled)
00717 fReset->SetState(kButtonUp);
00718 }
00719
00720
00721 void TFitParametersDialog::DoParValue()
00722 {
00723
00724
00725 TGNumberEntry *ne = (TGNumberEntry *) gTQSender;
00726 Int_t id = ne->WidgetId();
00727
00728 for (Int_t i = 0; i < fNP; i++ ) {
00729 if (id == kVAL*fNP+i) {
00730 if (fParVal[i]->GetNumber() < fParMin[i]->GetNumber()) {
00731 Double_t extraIncrement = (fParMax[i]->GetNumber() - fParMin[i]->GetNumber()) / 4;
00732 fParMin[i]->SetNumber(fParVal[i]->GetNumber() - extraIncrement );
00733 fClient->NeedRedraw(fParMin[i]);
00734 fParSld[i]->SetRange(fParMin[i]->GetNumber(),
00735 fParMax[i]->GetNumber());
00736 fParSld[i]->SetPosition(fParMin[i]->GetNumber(),
00737 fParMax[i]->GetNumber());
00738 }
00739 if (fParVal[i]->GetNumber() > fParMax[i]->GetNumber()) {
00740 Double_t extraIncrement = (fParMax[i]->GetNumber() - fParMin[i]->GetNumber()) / 4;
00741 fParMax[i]->SetNumber(fParVal[i]->GetNumber() + extraIncrement );
00742 fClient->NeedRedraw(fParMax[i]);
00743 fParSld[i]->SetRange(fParMin[i]->GetNumber(),
00744 fParMax[i]->GetNumber());
00745 fParSld[i]->SetPosition(fParMin[i]->GetNumber(),
00746 fParMax[i]->GetNumber());
00747 }
00748 fParSld[i]->SetPointerPosition(fParVal[i]->GetNumber());
00749 fClient->NeedRedraw(fParSld[i]);
00750 fFunc->SetParameter(i,fParSld[i]->GetPointerPosition());
00751 if (fParBnd[i]->GetState() == kButtonDown)
00752 fFunc->SetParLimits(i,fParSld[i]->GetMinPosition(),
00753 fParSld[i]->GetMaxPosition());
00754 else
00755 fFunc->ReleaseParameter(i);
00756 }
00757 }
00758 fHasChanges = kTRUE;
00759 if (fUpdate->GetState() == kButtonDown)
00760 DrawFunction();
00761 else if ((fApply->GetState() == kButtonDisabled) && fHasChanges)
00762 fApply->SetState(kButtonUp);
00763 if (fReset->GetState() == kButtonDisabled)
00764 fReset->SetState(kButtonUp);
00765 }
00766
00767
00768 void TFitParametersDialog::DoParMinLimit()
00769 {
00770
00771
00772 TGNumberEntryField *ne = (TGNumberEntryField *) gTQSender;
00773 Int_t id = ne->WidgetId();
00774
00775 for (Int_t i = 0; i < fNP; i++ ) {
00776 if (id == kMIN*fNP+i) {
00777 if ((fParMin[i]->GetNumber() >= fParMax[i]->GetNumber()) &&
00778 (fParBnd[i]->GetState() == kButtonDown)) {
00779 Int_t ret;
00780 const char *txt;
00781 txt = "'Min' cannot be bigger then 'Max' if this parameter is bounded.";
00782 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
00783 "Parameter Limits", txt, kMBIconExclamation, kMBOk, &ret);
00784 fParMin[i]->SetNumber(fParVal[i]->GetNumber()-fParStp[i]->GetNumber());
00785 return;
00786 }
00787 if (fParBnd[i]->GetState() == kButtonDown) {
00788 Double_t val = (fParMax[i]->GetNumber()+fParMin[i]->GetNumber())/2.;
00789 fParVal[i]->SetNumber(val);
00790 fParVal[i]->SetLimitValues(fParMin[i]->GetNumber(),
00791 fParMax[i]->GetNumber());
00792 }
00793 fParSld[i]->SetRange(fParMin[i]->GetNumber(),
00794 fParMax[i]->GetNumber());
00795 fParSld[i]->SetPosition(fParMin[i]->GetNumber(),
00796 fParMax[i]->GetNumber());
00797 fParSld[i]->SetPointerPosition(fParVal[i]->GetNumber());
00798 fClient->NeedRedraw(fParSld[i]);
00799 }
00800 }
00801 fHasChanges = kTRUE;
00802 if (fUpdate->GetState() == kButtonDown)
00803 DrawFunction();
00804 else if ((fApply->GetState() == kButtonDisabled) && fHasChanges)
00805 fApply->SetState(kButtonUp);
00806 if (fReset->GetState() == kButtonDisabled)
00807 fReset->SetState(kButtonUp);
00808 }
00809
00810
00811 void TFitParametersDialog::DoParMaxLimit()
00812 {
00813
00814
00815 TGNumberEntryField *ne = (TGNumberEntryField *) gTQSender;
00816 Int_t id = ne->WidgetId();
00817
00818 for (Int_t i = 0; i < fNP; i++ ) {
00819 if (id == kMAX*fNP+i) {
00820 if ((fParMin[i]->GetNumber() >= fParMax[i]->GetNumber()) &&
00821 (fParBnd[i]->GetState() == kButtonDown)) {
00822 Int_t ret;
00823 const char *txt;
00824 txt = "'Min' cannot be bigger then 'Max' if this parameter is bounded.";
00825 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
00826 "Parameter Limits", txt, kMBIconExclamation, kMBOk, &ret);
00827 fParMax[i]->SetNumber(fParVal[i]->GetNumber()+fParStp[i]->GetNumber());
00828 return;
00829 }
00830 if (fParBnd[i]->GetState() == kButtonDown) {
00831 Double_t val = (fParMax[i]->GetNumber()+(fParMin[i]->GetNumber()))/2.;
00832 fParVal[i]->SetNumber(val);
00833 fParVal[i]->SetLimitValues(fParMin[i]->GetNumber(),
00834 fParMax[i]->GetNumber());
00835 }
00836 fParSld[i]->SetRange(fParMin[i]->GetNumber(),
00837 fParMax[i]->GetNumber());
00838 fParSld[i]->SetPosition(fParMin[i]->GetNumber(),
00839 fParMax[i]->GetNumber());
00840 fParSld[i]->SetPointerPosition(fParVal[i]->GetNumber());
00841 fClient->NeedRedraw(fParSld[i]);
00842 }
00843 }
00844 fHasChanges = kTRUE;
00845 if (fUpdate->GetState() == kButtonDown)
00846 DrawFunction();
00847 else if ((fApply->GetState() == kButtonDisabled) && fHasChanges)
00848 fApply->SetState(kButtonUp);
00849 if (fReset->GetState() == kButtonDisabled)
00850 fReset->SetState(kButtonUp);
00851 }
00852
00853
00854 void TFitParametersDialog::DrawFunction()
00855 {
00856
00857
00858 if ( !fFpad ) return;
00859 TVirtualPad *save = 0;
00860 save = gPad;
00861 gPad = fFpad;
00862 gPad->cd();
00863
00864 Style_t st = fFunc->GetLineStyle();
00865 fFunc->SetLineStyle(2);
00866
00867 TString opt = fFunc->GetDrawOption();
00868 opt.ToUpper();
00869 if (!opt.Contains("SAME"))
00870 opt += "SAME";
00871
00872 fFunc->Draw(opt);
00873 gPad->Modified();
00874 gPad->Update();
00875 fHasChanges = kFALSE;
00876
00877 fFunc->SetLineStyle(st);
00878 if (save) gPad = save;
00879 *fRetCode = kFPDBounded;
00880 }
00881
00882
00883 void TFitParametersDialog::HandleButtons(Bool_t update)
00884 {
00885
00886
00887 if (update && fHasChanges)
00888 DrawFunction();
00889 else if ((fApply->GetState() == kButtonDisabled) && fHasChanges) {
00890 fApply->SetState(kButtonUp);
00891 }
00892 }
00893
00894
00895 void TFitParametersDialog::DisconnectSlots()
00896 {
00897
00898
00899 for (Int_t i = 0; i < fNP; i++ ) {
00900 fParFix[i]->Disconnect("Toggled(Bool_t)");
00901 fParBnd[i]->Disconnect("Toggled(Bool_t)");
00902 fParVal[i]->Disconnect("ValueSet(Long_t)");
00903 fParMin[i]->Disconnect("ReturnPressed()");
00904 fParMax[i]->Disconnect("ReturnPressed()");
00905 fParSld[i]->Disconnect("PointerPositionChanged()");
00906 fParSld[i]->Disconnect("PositionChanged()");
00907 fParStp[i]->Disconnect("ValueSet(Long_t)");
00908 }
00909 fUpdate->Disconnect("Toggled(Bool_t)");
00910 fReset->Disconnect("Clicked()");
00911 fApply->Disconnect("Clicked()");
00912 fOK->Disconnect("Clicked()");
00913 fCancel->Disconnect("Clicked()");
00914 }
00915