00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TROOT.h"
00013 #include "TMultiGraph.h"
00014 #include "TGraph.h"
00015 #include "TH1.h"
00016 #include "TVirtualPad.h"
00017 #include "Riostream.h"
00018 #include "TVirtualFitter.h"
00019 #include "TPluginManager.h"
00020 #include "TClass.h"
00021 #include "TMath.h"
00022 #include "TSystem.h"
00023 #include <stdlib.h>
00024
00025 #include "HFitInterface.h"
00026 #include "Fit/DataRange.h"
00027 #include "Math/MinimizerOptions.h"
00028
00029 #include <ctype.h>
00030
00031 extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
00032
00033 ClassImp(TMultiGraph)
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 TMultiGraph::TMultiGraph(): TNamed()
00063 {
00064
00065
00066 fGraphs = 0;
00067 fFunctions = 0;
00068 fHistogram = 0;
00069 fMaximum = -1111;
00070 fMinimum = -1111;
00071 }
00072
00073
00074
00075 TMultiGraph::TMultiGraph(const char *name, const char *title)
00076 : TNamed(name,title)
00077 {
00078
00079
00080 fGraphs = 0;
00081 fFunctions = 0;
00082 fHistogram = 0;
00083 fMaximum = -1111;
00084 fMinimum = -1111;
00085 }
00086
00087
00088
00089 TMultiGraph::TMultiGraph(const TMultiGraph& mg) :
00090 TNamed (mg),
00091 fGraphs(mg.fGraphs),
00092 fFunctions(mg.fFunctions),
00093 fHistogram(mg.fHistogram),
00094 fMaximum(mg.fMaximum),
00095 fMinimum(mg.fMinimum)
00096 {
00097
00098 }
00099
00100
00101
00102 TMultiGraph& TMultiGraph::operator=(const TMultiGraph& mg)
00103 {
00104
00105 if(this!=&mg) {
00106 TNamed::operator=(mg);
00107 fGraphs=mg.fGraphs;
00108 fFunctions=mg.fFunctions;
00109 fHistogram=mg.fHistogram;
00110 fMaximum=mg.fMaximum;
00111 fMinimum=mg.fMinimum;
00112 }
00113 return *this;
00114 }
00115
00116
00117
00118 TMultiGraph::~TMultiGraph()
00119 {
00120
00121
00122 if (!fGraphs) return;
00123 TGraph *g;
00124 TIter next(fGraphs);
00125 while ((g = (TGraph*) next())) {
00126 g->ResetBit(kMustCleanup);
00127 }
00128 fGraphs->Delete();
00129 delete fGraphs;
00130 fGraphs = 0;
00131 delete fHistogram;
00132 fHistogram = 0;
00133 if (fFunctions) {
00134 fFunctions->SetBit(kInvalidObject);
00135
00136
00137
00138
00139 TObject *obj;
00140 while ((obj = fFunctions->First())) {
00141 while(fFunctions->Remove(obj)) { }
00142 delete obj;
00143 }
00144 delete fFunctions;
00145 }
00146 }
00147
00148
00149
00150 void TMultiGraph::Add(TGraph *graph, Option_t *chopt)
00151 {
00152
00153
00154
00155
00156
00157 if (!fGraphs) fGraphs = new TList();
00158 graph->SetBit(kMustCleanup);
00159 fGraphs->Add(graph,chopt);
00160 }
00161
00162
00163
00164 void TMultiGraph::Add(TMultiGraph *multigraph, Option_t *chopt)
00165 {
00166
00167
00168 TList *graphlist = multigraph->GetListOfGraphs();
00169 if (!graphlist) return;
00170
00171 if (!fGraphs) fGraphs = new TList();
00172
00173 TGraph *gr;
00174 gr = (TGraph*)graphlist->First();
00175 fGraphs->Add(gr,chopt);
00176 for(Int_t i = 1; i < graphlist->GetSize(); i++){
00177 gr = (TGraph*)graphlist->After(gr);
00178 fGraphs->Add(gr,chopt);
00179 }
00180 }
00181
00182
00183
00184 void TMultiGraph::Browse(TBrowser *)
00185 {
00186
00187
00188 Draw("alp");
00189 gPad->Update();
00190 }
00191
00192
00193
00194 Int_t TMultiGraph::DistancetoPrimitive(Int_t px, Int_t py)
00195 {
00196
00197
00198
00199 const Int_t kMaxDiff = 10;
00200 Int_t distance = 9999;
00201 if (fHistogram) {
00202 distance = fHistogram->DistancetoPrimitive(px,py);
00203 if (distance <= 0) return distance;
00204 }
00205
00206
00207 if (!fGraphs) return distance;
00208 TGraph *g;
00209 TIter next(fGraphs);
00210 while ((g = (TGraph*) next())) {
00211 Int_t dist = g->DistancetoPrimitive(px,py);
00212 if (dist <= 0) return 0;
00213 if (dist < kMaxDiff) {gPad->SetSelected(g); return dist;}
00214 }
00215 return distance;
00216 }
00217
00218
00219
00220 void TMultiGraph::Draw(Option_t *option)
00221 {
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 AppendPad(option);
00235 }
00236
00237
00238
00239 TFitResultPtr TMultiGraph::Fit(const char *fname, Option_t *option, Option_t *, Axis_t xmin, Axis_t xmax)
00240 {
00241
00242
00243
00244
00245 char *linear;
00246 linear= (char*)strstr(fname, "++");
00247 TF1 *f1=0;
00248 if (linear)
00249 f1=new TF1(fname, fname, xmin, xmax);
00250 else {
00251 f1 = (TF1*)gROOT->GetFunction(fname);
00252 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
00253 }
00254
00255 return Fit(f1,option,"",xmin,xmax);
00256 }
00257
00258
00259
00260 TFitResultPtr TMultiGraph::Fit(TF1 *f1, Option_t *option, Option_t *goption, Axis_t rxmin, Axis_t rxmax)
00261 {
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 Foption_t fitOption;
00402 ROOT::Fit::FitOptionsMake(option,fitOption);
00403
00404
00405 ROOT::Fit::DataRange range(rxmin,rxmax);
00406 ROOT::Math::MinimizerOptions minOption;
00407 return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
00408
00409 }
00410
00411
00412 void TMultiGraph::FitPanel()
00413 {
00414
00415
00416
00417
00418
00419 if (!gPad)
00420 gROOT->MakeDefCanvas();
00421
00422 if (!gPad) {
00423 Error("FitPanel", "Unable to create a default canvas");
00424 return;
00425 }
00426
00427
00428 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
00429 if (handler && handler->LoadPlugin() != -1) {
00430 if (handler->ExecPlugin(2, gPad, this) == 0)
00431 Error("FitPanel", "Unable to crate the FitPanel");
00432 }
00433 else
00434 Error("FitPanel", "Unable to find the FitPanel plug-in");
00435 }
00436
00437
00438 Option_t *TMultiGraph::GetGraphDrawOption(const TGraph *gr) const
00439 {
00440
00441
00442
00443 if (!fGraphs || !gr) return "";
00444 TListIter next(fGraphs);
00445 TObject *obj;
00446 while ((obj = next())) {
00447 if (obj == (TObject*)gr) return next.GetOption();
00448 }
00449 return "";
00450 }
00451
00452
00453
00454 void TMultiGraph::InitGaus(Double_t xmin, Double_t xmax)
00455 {
00456
00457
00458 Double_t allcha, sumx, sumx2, x, val, rms, mean;
00459 Int_t bin;
00460 const Double_t sqrtpi = 2.506628;
00461
00462
00463 Int_t np = 0;
00464 allcha = sumx = sumx2 = 0;
00465 TGraph *g;
00466 TIter next(fGraphs);
00467 Double_t *px, *py;
00468 Int_t npp;
00469 while ((g = (TGraph*) next())) {
00470 px=g->GetX();
00471 py=g->GetY();
00472 npp=g->GetN();
00473 for (bin=0; bin<npp; bin++){
00474 x=px[bin];
00475 if (x<xmin || x>xmax) continue;
00476 np++;
00477 val=py[bin];
00478 sumx+=val*x;
00479 sumx2+=val*x*x;
00480 allcha+=val;
00481 }
00482 }
00483 if (np == 0 || allcha == 0) return;
00484 mean = sumx/allcha;
00485 rms = TMath::Sqrt(sumx2/allcha - mean*mean);
00486
00487 Double_t binwidx = TMath::Abs((xmax-xmin)/np);
00488 if (rms == 0) rms = 1;
00489 TVirtualFitter *grFitter = TVirtualFitter::GetFitter();
00490 TF1 *f1 = (TF1*)grFitter->GetUserFunc();
00491 f1->SetParameter(0,binwidx*allcha/(sqrtpi*rms));
00492 f1->SetParameter(1,mean);
00493 f1->SetParameter(2,rms);
00494 f1->SetParLimits(2,0,10*rms);
00495 }
00496
00497
00498
00499 void TMultiGraph::InitExpo(Double_t xmin, Double_t xmax)
00500 {
00501
00502
00503 Double_t constant, slope;
00504 Int_t ifail;
00505
00506 LeastSquareLinearFit(-1, constant, slope, ifail, xmin, xmax);
00507
00508 TVirtualFitter *grFitter = TVirtualFitter::GetFitter();
00509 TF1 *f1 = (TF1*)grFitter->GetUserFunc();
00510 f1->SetParameter(0,constant);
00511 f1->SetParameter(1,slope);
00512 }
00513
00514
00515
00516 void TMultiGraph::InitPolynom(Double_t xmin, Double_t xmax)
00517 {
00518
00519
00520 Double_t fitpar[25];
00521
00522 TVirtualFitter *grFitter = TVirtualFitter::GetFitter();
00523 TF1 *f1 = (TF1*)grFitter->GetUserFunc();
00524 Int_t npar = f1->GetNpar();
00525
00526 LeastSquareFit(npar, fitpar, xmin, xmax);
00527
00528 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
00529 }
00530
00531
00532
00533 void TMultiGraph::LeastSquareFit(Int_t m, Double_t *a, Double_t xmin, Double_t xmax)
00534 {
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 const Double_t zero = 0.;
00545 const Double_t one = 1.;
00546 const Int_t idim = 20;
00547
00548 Double_t b[400] ;
00549 Int_t i, k, l, ifail, bin;
00550 Double_t power;
00551 Double_t da[20], xk, yk;
00552
00553
00554
00555 TGraph *g;
00556 TIter next(fGraphs);
00557 Double_t *px, *py;
00558 Int_t n=0;
00559 Int_t npp;
00560 while ((g = (TGraph*) next())) {
00561 px=g->GetX();
00562 npp=g->GetN();
00563 for (bin=0; bin<npp; bin++){
00564 xk=px[bin];
00565 if (xk < xmin || xk > xmax) continue;
00566 n++;
00567 }
00568 }
00569 if (m <= 2) {
00570 LeastSquareLinearFit(n, a[0], a[1], ifail, xmin, xmax);
00571 return;
00572 }
00573 if (m > idim || m > n) return;
00574 da[0] = zero;
00575 for (l = 2; l <= m; ++l) {
00576 b[l-1] = zero;
00577 b[m + l*20 - 21] = zero;
00578 da[l-1] = zero;
00579 }
00580 Int_t np = 0;
00581
00582 next.Reset();
00583 while ((g = (TGraph*) next())) {
00584 px=g->GetX();
00585 py=g->GetY();
00586 npp=g->GetN();
00587
00588 for (k = 0; k <= npp; ++k) {
00589 xk = px[k];
00590 if (xk < xmin || xk > xmax) continue;
00591 np++;
00592 yk = py[k];
00593 power = one;
00594 da[0] += yk;
00595 for (l = 2; l <= m; ++l) {
00596 power *= xk;
00597 b[l-1] += power;
00598 da[l-1] += power*yk;
00599 }
00600 for (l = 2; l <= m; ++l) {
00601 power *= xk;
00602 b[m + l*20 - 21] += power;
00603 }
00604 }
00605 }
00606 b[0] = Double_t(np);
00607 for (i = 3; i <= m; ++i) {
00608 for (k = i; k <= m; ++k) {
00609 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
00610 }
00611 }
00612 H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
00613
00614 if (ifail < 0) {
00615
00616 py=((TGraph *)fGraphs->First())->GetY();
00617 a[0]=py[0];
00618 for (i=1; i<m; ++i) a[i] = 0;
00619 return;
00620 }
00621 for (i=0; i<m; ++i) a[i] = da[i];
00622 }
00623
00624
00625
00626 void TMultiGraph::LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail, Double_t xmin, Double_t xmax)
00627 {
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 Double_t xbar, ybar, x2bar;
00639 Int_t i;
00640 Double_t xybar;
00641 Double_t fn, xk, yk;
00642 Double_t det;
00643
00644 ifail = -2;
00645 xbar = ybar = x2bar = xybar = 0;
00646 Int_t np = 0;
00647 TGraph *g;
00648 TIter next(fGraphs);
00649 Double_t *px, *py;
00650 Int_t npp;
00651 while ((g = (TGraph*) next())) {
00652 px=g->GetX();
00653 py=g->GetY();
00654 npp=g->GetN();
00655 for (i = 0; i < npp; ++i) {
00656 xk = px[i];
00657 if (xk < xmin || xk > xmax) continue;
00658 np++;
00659 yk = py[i];
00660 if (ndata < 0) {
00661 if (yk <= 0) yk = 1e-9;
00662 yk = TMath::Log(yk);
00663 }
00664 xbar += xk;
00665 ybar += yk;
00666 x2bar += xk*xk;
00667 xybar += xk*yk;
00668 }
00669 }
00670 fn = Double_t(np);
00671 det = fn*x2bar - xbar*xbar;
00672 ifail = -1;
00673 if (det <= 0) {
00674 if (fn > 0) a0 = ybar/fn;
00675 else a0 = 0;
00676 a1 = 0;
00677 return;
00678 }
00679 ifail = 0;
00680 a0 = (x2bar*ybar - xbar*xybar) / det;
00681 a1 = (fn*xybar - xbar*ybar) / det;
00682 }
00683
00684
00685
00686 Int_t TMultiGraph::IsInside(Double_t x, Double_t y) const
00687 {
00688
00689
00690 Int_t in = 0;
00691 if (!fGraphs) return in;
00692 TGraph *g;
00693 TIter next(fGraphs);
00694 while ((g = (TGraph*) next())) {
00695 in = g->IsInside(x, y);
00696 if (in) return in;
00697 }
00698 return in;
00699 }
00700
00701
00702
00703 TH1F *TMultiGraph::GetHistogram() const
00704 {
00705
00706
00707
00708
00709
00710 if (fHistogram) return fHistogram;
00711 if (!gPad) return 0;
00712 gPad->Modified();
00713 gPad->Update();
00714 if (fHistogram) return fHistogram;
00715 TH1F *h1 = (TH1F*)gPad->FindObject("hframe");
00716 return h1;
00717 }
00718
00719
00720
00721 TF1 *TMultiGraph::GetFunction(const char *name) const
00722 {
00723
00724
00725
00726
00727
00728 if (!fFunctions) return 0;
00729 return (TF1*)fFunctions->FindObject(name);
00730 }
00731
00732
00733 TList *TMultiGraph::GetListOfFunctions()
00734 {
00735
00736
00737
00738 if (!fFunctions) fFunctions = new TList();
00739 return fFunctions;
00740 }
00741
00742
00743
00744 TAxis *TMultiGraph::GetXaxis() const
00745 {
00746
00747
00748 if (!gPad) return 0;
00749 TH1 *h = GetHistogram();
00750 if (!h) return 0;
00751 return h->GetXaxis();
00752 }
00753
00754
00755
00756 TAxis *TMultiGraph::GetYaxis() const
00757 {
00758
00759
00760 if (!gPad) return 0;
00761 TH1 *h = GetHistogram();
00762 if (!h) return 0;
00763 return h->GetYaxis();
00764 }
00765
00766
00767
00768 void TMultiGraph::Paint(Option_t *option)
00769 {
00770
00771
00772 if (!fGraphs) return;
00773 if (fGraphs->GetSize() == 0) return;
00774
00775 char *l;
00776 static char chopt[33];
00777 Int_t nch = strlen(option);
00778 Int_t i;
00779 for (i=0;i<nch;i++) chopt[i] = toupper(option[i]);
00780 chopt[nch] = 0;
00781 TGraph *g;
00782
00783 l = strstr(chopt,"A");
00784 if (l) {
00785 *l = ' ';
00786 TIter next(fGraphs);
00787 Int_t npt = 100;
00788 Double_t maximum, minimum, rwxmin, rwxmax, rwymin, rwymax, uxmin, uxmax, dx, dy;
00789 rwxmin = gPad->GetUxmin();
00790 rwxmax = gPad->GetUxmax();
00791 rwymin = gPad->GetUymin();
00792 rwymax = gPad->GetUymax();
00793 char *xtitle = 0;
00794 char *ytitle = 0;
00795 Int_t firstx = 0;
00796 Int_t lastx = 0;
00797
00798 if (fHistogram) {
00799
00800 if (fHistogram->GetMinimum() >= fHistogram->GetMaximum()) {
00801 nch = strlen(fHistogram->GetXaxis()->GetTitle());
00802 firstx = fHistogram->GetXaxis()->GetFirst();
00803 lastx = fHistogram->GetXaxis()->GetLast();
00804 if (nch) {
00805 xtitle = new char[nch+1];
00806 strlcpy(xtitle,fHistogram->GetXaxis()->GetTitle(),nch+1);
00807 }
00808 nch = strlen(fHistogram->GetYaxis()->GetTitle());
00809 if (nch) {
00810 ytitle = new char[nch+1];
00811 strlcpy(ytitle,fHistogram->GetYaxis()->GetTitle(),nch+1);
00812 }
00813 delete fHistogram;
00814 fHistogram = 0;
00815 }
00816 }
00817 if (fHistogram) {
00818 minimum = fHistogram->GetYaxis()->GetXmin();
00819 maximum = fHistogram->GetYaxis()->GetXmax();
00820 uxmin = gPad->PadtoX(rwxmin);
00821 uxmax = gPad->PadtoX(rwxmax);
00822 } else {
00823 g = (TGraph*) next();
00824 if (g) g->ComputeRange(rwxmin, rwymin, rwxmax, rwymax);
00825 while ((g = (TGraph*) next())) {
00826 Double_t rx1,ry1,rx2,ry2;
00827 g->ComputeRange(rx1, ry1, rx2, ry2);
00828 if (rx1 < rwxmin) rwxmin = rx1;
00829 if (ry1 < rwymin) rwymin = ry1;
00830 if (rx2 > rwxmax) rwxmax = rx2;
00831 if (ry2 > rwymax) rwymax = ry2;
00832 if (g->GetN() > npt) npt = g->GetN();
00833 }
00834 if (rwxmin == rwxmax) rwxmax += 1.;
00835 if (rwymin == rwymax) rwymax += 1.;
00836 dx = 0.05*(rwxmax-rwxmin);
00837 dy = 0.05*(rwymax-rwymin);
00838 uxmin = rwxmin - dx;
00839 uxmax = rwxmax + dx;
00840 if (gPad->GetLogy()) {
00841 if (rwymin <= 0) rwymin = 0.001*rwymax;
00842 minimum = rwymin/(1+0.5*TMath::Log10(rwymax/rwymin));
00843 maximum = rwymax*(1+0.2*TMath::Log10(rwymax/rwymin));
00844 } else {
00845 minimum = rwymin - dy;
00846 maximum = rwymax + dy;
00847 }
00848 if (minimum < 0 && rwymin >= 0) minimum = 0;
00849 if (maximum > 0 && rwymax <= 0) maximum = 0;
00850 }
00851
00852 if (fMinimum != -1111) rwymin = minimum = fMinimum;
00853 if (fMaximum != -1111) rwymax = maximum = fMaximum;
00854 if (uxmin < 0 && rwxmin >= 0) {
00855 if (gPad->GetLogx()) uxmin = 0.9*rwxmin;
00856
00857 }
00858 if (uxmax > 0 && rwxmax <= 0) {
00859 if (gPad->GetLogx()) uxmax = 1.1*rwxmax;
00860
00861 }
00862 if (minimum < 0 && rwymin >= 0) {
00863 if(gPad->GetLogy()) minimum = 0.9*rwymin;
00864
00865 }
00866 if (maximum > 0 && rwymax <= 0) {
00867 if(gPad->GetLogy()) maximum = 1.1*rwymax;
00868
00869 }
00870 if (minimum <= 0 && gPad->GetLogy()) minimum = 0.001*maximum;
00871 if (uxmin <= 0 && gPad->GetLogx()) {
00872 if (uxmax > 1000) uxmin = 1;
00873 else uxmin = 0.001*uxmax;
00874 }
00875 rwymin = minimum;
00876 rwymax = maximum;
00877 if (fHistogram) {
00878 fHistogram->GetYaxis()->SetLimits(rwymin,rwymax);
00879 }
00880
00881
00882 if (!fHistogram) {
00883
00884
00885 rwxmin = uxmin;
00886 rwxmax = uxmax;
00887 fHistogram = new TH1F(GetName(),GetTitle(),npt,rwxmin,rwxmax);
00888 if (!fHistogram) return;
00889 fHistogram->SetMinimum(rwymin);
00890 fHistogram->SetBit(TH1::kNoStats);
00891 fHistogram->SetMaximum(rwymax);
00892 fHistogram->GetYaxis()->SetLimits(rwymin,rwymax);
00893 fHistogram->SetDirectory(0);
00894 if (xtitle) {fHistogram->GetXaxis()->SetTitle(xtitle); delete [] xtitle;}
00895 if (ytitle) {fHistogram->GetYaxis()->SetTitle(ytitle); delete [] ytitle;}
00896 if (firstx != lastx) fHistogram->GetXaxis()->SetRange(firstx,lastx);
00897 }
00898 fHistogram->Paint("0");
00899 }
00900
00901 TGraph *gfit = 0;
00902 if (fGraphs) {
00903 TObjOptLink *lnk = (TObjOptLink*)fGraphs->FirstLink();
00904 TObject *obj = 0;
00905
00906 while (lnk) {
00907 obj = lnk->GetObject();
00908 if (strlen(lnk->GetOption())) obj->Paint(lnk->GetOption());
00909 else obj->Paint(chopt);
00910 lnk = (TObjOptLink*)lnk->Next();
00911 }
00912 gfit = (TGraph*)obj;
00913 }
00914
00915 TObject *f;
00916 TF1 *fit = 0;
00917 if (fFunctions) {
00918 TIter next(fFunctions);
00919 while ((f = (TObject*) next())) {
00920 if (f->InheritsFrom(TF1::Class())) {
00921 if (f->TestBit(TF1::kNotDraw) == 0) f->Paint("lsame");
00922 fit = (TF1*)f;
00923 } else {
00924 f->Paint();
00925 }
00926 }
00927 }
00928
00929 if (fit) gfit->PaintStats(fit);
00930 }
00931
00932
00933
00934 void TMultiGraph::Print(Option_t *option) const
00935 {
00936
00937
00938 TGraph *g;
00939 if (fGraphs) {
00940 TIter next(fGraphs);
00941 while ((g = (TGraph*) next())) {
00942 g->Print(option);
00943 }
00944 }
00945 }
00946
00947
00948
00949 void TMultiGraph::RecursiveRemove(TObject *obj)
00950 {
00951
00952
00953
00954 if (!fGraphs) return;
00955 TObject *objr = fGraphs->Remove(obj);
00956 if (!objr) return;
00957 delete fHistogram; fHistogram = 0;
00958 if (gPad) gPad->Modified();
00959 }
00960
00961
00962
00963 void TMultiGraph::SavePrimitive(ostream &out, Option_t *option )
00964 {
00965
00966
00967 char quote = '"';
00968 out<<" "<<endl;
00969 if (gROOT->ClassSaved(TMultiGraph::Class())) {
00970 out<<" ";
00971 } else {
00972 out<<" TMultiGraph *";
00973 }
00974 out<<"multigraph = new TMultiGraph();"<<endl;
00975 out<<" multigraph->SetName("<<quote<<GetName()<<quote<<");"<<endl;
00976 out<<" multigraph->SetTitle("<<quote<<GetTitle()<<quote<<");"<<endl;
00977
00978 if (fGraphs) {
00979 TObjOptLink *lnk = (TObjOptLink*)fGraphs->FirstLink();
00980 TObject *g;
00981
00982 while (lnk) {
00983 g = lnk->GetObject();
00984 g->SavePrimitive(out, Form("multigraph%s",lnk->GetOption()));
00985 lnk = (TObjOptLink*)lnk->Next();
00986 }
00987 }
00988 const char *l = strstr(option,"th2poly");
00989 if (l) {
00990 out<<" "<<l+7<<"->AddBin(multigraph);"<<endl;
00991 } else {
00992 out<<" multigraph->Draw(" <<quote<<option<<quote<<");"<<endl;
00993 }
00994 TAxis *xaxis = GetXaxis();
00995 TAxis *yaxis = GetYaxis();
00996
00997 if (xaxis) xaxis->SaveAttributes(out, "multigraph","->GetXaxis()");
00998 if (yaxis) yaxis->SaveAttributes(out, "multigraph","->GetYaxis()");
00999 }
01000
01001
01002
01003 void TMultiGraph::SetMaximum(Double_t maximum)
01004 {
01005
01006
01007 fMaximum = maximum;
01008 if (fHistogram) fHistogram->SetMaximum(maximum);
01009 }
01010
01011
01012
01013 void TMultiGraph::SetMinimum(Double_t minimum)
01014 {
01015
01016
01017 fMinimum = minimum;
01018 if (fHistogram) fHistogram->SetMinimum(minimum);
01019 }