TGraph2D.cxx

Go to the documentation of this file.
00001 // @(#)root/hist:$Id: TGraph2D.cxx,v 1.00
00002 // Author: Olivier Couet
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "Riostream.h"
00013 #include "TROOT.h"
00014 #include "TMath.h"
00015 #include "TH2.h"
00016 #include "TF2.h"
00017 #include "TList.h"
00018 #include "TGraph2D.h"
00019 #include "TGraphDelaunay.h"
00020 #include "TVirtualPad.h"
00021 #include "TVirtualFitter.h"
00022 #include "TPluginManager.h"
00023 #include "TClass.h"
00024 #include "TSystem.h"
00025 #include <stdlib.h>
00026 
00027 #include "HFitInterface.h"
00028 #include "Fit/DataRange.h"
00029 #include "Math/MinimizerOptions.h"
00030 
00031 ClassImp(TGraph2D)
00032 
00033 
00034 //______________________________________________________________________________
00035 /* Begin_Html
00036 <center><h2>Graph 2D class</h2></center>
00037 A Graph2D is a graphics object made of three arrays X, Y and Z with the same
00038 number of points each.
00039 <p>
00040 This class has different constructors:
00041 <ol>
00042 <p><li> With an array's dimension and three arrays x, y, and z:
00043 <pre>
00044    TGraph2D *g = new TGraph2D(n, x, y, z);
00045 </pre>
00046     x, y, z arrays can be doubles, floats, or ints.
00047 
00048 <p><li> With an array's dimension only:
00049 <pre>
00050    TGraph2D *g = new TGraph2D(n);
00051 </pre>
00052    The internal arrays are then filled with SetPoint. The following line
00053    fills the the internal arrays at the position "i" with the values x,y,z.
00054 <pre>
00055    g->SetPoint(i, x, y, z);
00056 </pre>
00057 <p><li> Without parameters:
00058 <pre>
00059    TGraph2D *g = new TGraph2D();
00060 </pre>
00061    again SetPoint must be used to fill the internal arrays.
00062 <p><li> From a file:
00063 <pre>
00064    TGraph2D *g = new TGraph2D("graph.dat");
00065 </pre>
00066    Arrays are read from the ASCII file "graph.dat" according to a specifies
00067    format. The format's default value is "%lg %lg %lg"
00068 </ol>
00069 
00070 Note that in any of these three cases, SetPoint can be used to change a data
00071 point or add a new one. If the data point index (i) is greater than the
00072 current size of the internal arrays, they are automatically extended.
00073 <p>
00074 Specific drawing options can be used to paint a TGraph2D:
00075 
00076 <table border=0>
00077 
00078 <tr><th valign=top>"TRI"</th><td>
00079 The Delaunay triangles are drawn using filled area.
00080 An hidden surface drawing technique is used. The surface is
00081 painted with the current fill area color. The edges of each
00082 triangles are painted with the current line color.
00083 </td></tr>
00084 
00085 <tr><th valign=top>"TRIW</th><td>
00086 The Delaunay triangles are drawn as wire frame
00087 </td></tr>
00088 
00089 <tr><th valign=top>"TRI1</th><td>
00090 The Delaunay triangles are painted with color levels. The edges
00091 of each triangles are painted with the current line color.
00092 </td></tr>
00093 
00094 <tr><th valign=top>"TRI2</th><td>
00095 the Delaunay triangles are painted with color levels.
00096 </td></tr>
00097 
00098 <tr><th valign=top>"P"  </th><td>
00099 Draw a marker at each vertex
00100 </td></tr>
00101 
00102 <tr><th valign=top>"P0" </th><td>
00103 Draw a circle at each vertex. Each circle background is white.
00104 </td></tr>
00105 
00106 <tr><th valign=top>"PCOL" </th><td>
00107 Draw a marker at each vertex. The color of each marker is
00108 defined according to its Z position.
00109 </td></tr>
00110 
00111 <tr><th valign=top>"CONT" </th><td>
00112 Draw contours.
00113 </td></tr>
00114 
00115 <tr><th valign=top>"LINE" </th><td>
00116 Draw a 3D polyline.
00117 </td></tr>
00118 
00119 </table>
00120 
00121 A TGraph2D can be also drawn with ANY options valid to draw a 2D histogram.
00122 <p>
00123 When a TGraph2D is drawn with one of the 2D histogram drawing option,
00124 a intermediate 2D histogram is filled using the Delaunay triangles
00125 technique to interpolate the data set.
00126 <p>
00127 TGraph2D linearly interpolate a Z value for any (X,Y) point given some
00128 existing (X,Y,Z) points. The existing (X,Y,Z) points can be randomly
00129 scattered. The algorithm works by joining the existing points to make
00130 Delaunay triangles in (X,Y). These are then used to define flat planes
00131 in (X,Y,Z) over which to interpolate. The interpolated surface thus takes
00132 the form of tessellating triangles at various angles. Output can take the
00133 form of a 2D histogram or a vector. The triangles found can be drawn in 3D.
00134 <p>
00135 This software cannot be guaranteed to work under all circumstances. They
00136 were originally written to work with a few hundred points in an XY space
00137 with similar X and Y ranges.
00138 <p>
00139 Example:
00140 
00141 End_Html
00142 Begin_Macro(source)
00143 {
00144    TCanvas *c = new TCanvas("c","Graph2D example",0,0,600,400);
00145    Double_t x, y, z, P = 6.;
00146    Int_t np = 200;
00147    TGraph2D *dt = new TGraph2D();
00148    TRandom *r = new TRandom();
00149    for (Int_t N=0; N<np; N++) {
00150       x = 2*P*(r->Rndm(N))-P;
00151       y = 2*P*(r->Rndm(N))-P;
00152       z = (sin(x)/x)*(sin(y)/y)+0.2;
00153       dt->SetPoint(N,x,y,z);
00154    }
00155    gStyle->SetPalette(1);
00156    dt->Draw("surf1");
00157    return c;
00158 }
00159 End_Macro
00160 Begin_Html
00161 
00162 2D graphs can be fitted as shown by the following example:
00163 
00164 End_Html
00165 Begin_Macro(source)
00166 ../../../tutorials/fit/graph2dfit.C
00167 End_Macro
00168 Begin_Html
00169 
00170 Example showing the PCOL option.
00171 
00172 End_Html
00173 Begin_Macro(source)
00174 {
00175    TCanvas *c1 = new TCanvas("c1","Graph2D example",0,0,600,400);
00176    Double_t P = 5.;
00177    Int_t npx  = 20 ;
00178    Int_t npy  = 20 ;
00179    Double_t x = -P;
00180    Double_t y = -P;
00181    Double_t z;
00182    Int_t k = 0;
00183    Double_t dx = (2*P)/npx;
00184    Double_t dy = (2*P)/npy;
00185    TGraph2D *dt = new TGraph2D(npx*npy);
00186    dt->SetNpy(41);
00187    dt->SetNpx(40);
00188    for (Int_t i=0; i<npx; i++) {
00189       for (Int_t j=0; j<npy; j++) {
00190          z = sin(sqrt(x*x+y*y))+1;
00191          dt->SetPoint(k,x,y,z);
00192          k++;
00193          y = y+dx;
00194       }
00195       x = x+dx;
00196       y = -P;
00197    }
00198    gStyle->SetPalette(1);
00199    dt->SetMarkerStyle(20);
00200    dt->Draw("pcol");
00201    return c1;
00202 }
00203 End_Macro
00204 Begin_Html
00205 
00206 <h3>Definition of Delaunay triangulation (After B. Delaunay)</h3>
00207 For a set S of points in the Euclidean plane, the unique triangulation DT(S)
00208 of S such that no point in S is inside the circumcircle of any triangle in
00209 DT(S). DT(S) is the dual of the Voronoi diagram of S.
00210 If n is the number of points in S, the Voronoi diagram of S is the partitioning
00211 of the plane containing S points into n convex polygons such that each polygon
00212 contains exactly one point and every point in a given polygon is closer to its
00213 central point than to any other. A Voronoi diagram is sometimes also known as
00214 a Dirichlet tessellation.
00215 
00216 <img src="gif/dtvd.gif">
00217 
00218 <br>
00219 <a href="http://www.cs.cornell.edu/Info/People/chew/Delaunay.html">This applet</a>
00220 gives a nice practical view of Delaunay triangulation and Voronoi diagram.
00221 End_Html */
00222 
00223 
00224 //______________________________________________________________________________
00225 TGraph2D::TGraph2D()
00226          : TNamed("Graph2D","Graph2D"), TAttLine(1,1,1), TAttFill(0,1001),
00227            TAttMarker(), fNpoints(0)
00228 {
00229    // Graph2D default constructor
00230 
00231    fSize      = 0;
00232    fMargin    = 0.;
00233    fNpx       = 40;
00234    fNpy       = 40;
00235    fDirectory = 0;
00236    fHistogram = 0;
00237    fMaximum   = -1111;
00238    fMinimum   = -1111;
00239    fX         = 0;
00240    fY         = 0;
00241    fZ         = 0;
00242    fZout      = 0;
00243    fMaxIter   = 100000;
00244    fPainter   = 0;
00245    fFunctions = new TList;
00246    fUserHisto = kFALSE;
00247 }
00248 
00249 
00250 //______________________________________________________________________________
00251 TGraph2D::TGraph2D(Int_t n, Int_t *x, Int_t *y, Int_t *z)
00252          : TNamed("Graph2D","Graph2D"), TAttLine(1,1,1), TAttFill(0,1001),
00253            TAttMarker(), fNpoints(n)
00254 {
00255    // Graph2D constructor with three vectors of ints as input.
00256 
00257    Build(n);
00258 
00259    // Copy the input vectors into local arrays
00260    for (Int_t i=0; i<fNpoints; ++i) {
00261       fX[i] = (Double_t)x[i];
00262       fY[i] = (Double_t)y[i];
00263       fZ[i] = (Double_t)z[i];
00264    }
00265 }
00266 
00267 
00268 //______________________________________________________________________________
00269 TGraph2D::TGraph2D(Int_t n, Float_t *x, Float_t *y, Float_t *z)
00270          : TNamed("Graph2D","Graph2D"), TAttLine(1,1,1), TAttFill(0,1001),
00271            TAttMarker(), fNpoints(n)
00272 {
00273    // Graph2D constructor with three vectors of floats as input.
00274 
00275    Build(n);
00276 
00277    // Copy the input vectors into local arrays
00278    for (Int_t i=0; i<fNpoints; ++i) {
00279       fX[i] = x[i];
00280       fY[i] = y[i];
00281       fZ[i] = z[i];
00282    }
00283 }
00284 
00285 
00286 //______________________________________________________________________________
00287 TGraph2D::TGraph2D(Int_t n, Double_t *x, Double_t *y, Double_t *z)
00288          : TNamed("Graph2D","Graph2D"), TAttLine(1,1,1), TAttFill(0,1001),
00289            TAttMarker(), fNpoints(n)
00290 {
00291    // Graph2D constructor with three vectors of doubles as input.
00292 
00293    Build(n);
00294 
00295    // Copy the input vectors into local arrays
00296    for (Int_t i=0; i<fNpoints; ++i) {
00297       fX[i] = x[i];
00298       fY[i] = y[i];
00299       fZ[i] = z[i];
00300    }
00301 }
00302 
00303 
00304 //______________________________________________________________________________
00305 TGraph2D::TGraph2D(TH2 *h2)
00306          : TNamed("Graph2D","Graph2D"), TAttLine(1,1,1), TAttFill(0,1001),
00307            TAttMarker(), fNpoints(0)
00308 {
00309    // Graph2D constructor with a TH2 (h2) as input.
00310    // Only the h2's bins within the X and Y axis ranges are used.
00311    // Empty bins, recognized when both content and errors are zero, are excluded.
00312    Build(h2->GetNbinsX()*h2->GetNbinsY());
00313 
00314    TString gname = "Graph2D_from_" + TString(h2->GetName() );
00315    SetName(gname);
00316    // need to call later because sets title in ref histogram
00317    SetTitle(h2->GetTitle());
00318 
00319 
00320 
00321    TAxis *xaxis = h2->GetXaxis();
00322    TAxis *yaxis = h2->GetYaxis();
00323    Int_t xfirst = xaxis->GetFirst();
00324    Int_t xlast  = xaxis->GetLast();
00325    Int_t yfirst = yaxis->GetFirst();
00326    Int_t ylast  = yaxis->GetLast();
00327 
00328 
00329    Double_t x, y, z;
00330    Int_t k=0;
00331 
00332    for (Int_t i=xfirst; i<= xlast; i++) {
00333       for (Int_t j=yfirst; j<= ylast; j++) {
00334          x = xaxis->GetBinCenter(i);
00335          y = yaxis->GetBinCenter(j);
00336          z = h2->GetBinContent(i,j);
00337          Double_t ez = h2->GetBinError(i,j);
00338          if (z != 0. || ez != 0) {
00339             SetPoint(k, x, y, z);
00340             k++;
00341          }
00342       }
00343    }
00344 }
00345 
00346 
00347 //______________________________________________________________________________
00348 TGraph2D::TGraph2D(const char *name,const char *title,
00349                    Int_t n, Double_t *x, Double_t *y, Double_t *z)
00350          : TNamed(name,title), TAttLine(1,1,1), TAttFill(0,1001),
00351            TAttMarker(), fNpoints(n)
00352 {
00353    // Graph2D constructor with name, title and three vectors of doubles as input.
00354    // name   : name of 2D graph (avoid blanks)
00355    // title  : 2D graph title
00356    //          if title is of the form "stringt;stringx;stringy;stringz"
00357    //          the 2D graph title is set to stringt, the x axis title to stringx,
00358    //          the y axis title to stringy,etc
00359 
00360    Build(n);
00361 
00362    // Copy the input vectors into local arrays
00363    for (Int_t i=0; i<fNpoints; ++i) {
00364       fX[i] = x[i];
00365       fY[i] = y[i];
00366       fZ[i] = z[i];
00367    }
00368 }
00369 
00370 
00371 //______________________________________________________________________________
00372 TGraph2D::TGraph2D(Int_t n)
00373          : TNamed("Graph2D","Graph2D"), TAttLine(1,1,1), TAttFill(0,1001),
00374            TAttMarker(), fNpoints(0)
00375 {
00376    // Graph2D constructor. The arrays fX, fY and fZ should be filled via
00377    // calls to SetPoint
00378 
00379    Build(n);
00380 }
00381 
00382 
00383 //______________________________________________________________________________
00384 TGraph2D::TGraph2D(const char *filename, const char *format, Option_t *)
00385          : TNamed("Graph2D",filename), TAttLine(1,1,1), TAttFill(0,1001),
00386            TAttMarker(), fNpoints(0)
00387 {
00388    // Graph2D constructor reading input from filename
00389    // filename is assumed to contain at least three columns of numbers
00390 
00391    Build(100);
00392 
00393    Double_t x,y,z;
00394    FILE *fp = fopen(filename,"r");
00395    if (!fp) {
00396       MakeZombie();
00397       Error("TGraph2D", "Cannot open file: %s, TGraph2D is Zombie",filename);
00398       return;
00399    }
00400    char line[80];
00401    Int_t np = 0;
00402    while (fgets(line,80,fp)) {
00403       sscanf(&line[0],format,&x, &y, &z);
00404       SetPoint(np,x,y,z);
00405       np++;
00406    }
00407 
00408    fclose(fp);
00409 }
00410 
00411 
00412 //______________________________________________________________________________
00413 TGraph2D::TGraph2D(const TGraph2D &g)
00414          : TNamed(g), TAttLine(g), TAttFill(g), TAttMarker(g)
00415 {
00416    // Graph2D copy constructor.
00417 
00418    fNpoints = g.fNpoints;
00419    Build(fNpoints);
00420 
00421    for (Int_t n=0; n<fNpoints; n++) {
00422       fX[n] = g.fX[n];
00423       fY[n] = g.fY[n];
00424       fZ[n] = g.fZ[n];
00425    }
00426 }
00427 
00428 
00429 //______________________________________________________________________________
00430 TGraph2D::~TGraph2D()
00431 {
00432    // TGraph2D destructor.
00433 
00434    Clear();
00435 }
00436 
00437 
00438 //______________________________________________________________________________
00439 TGraph2D& TGraph2D::operator=(const TGraph2D &g)
00440 {
00441    // Graph2D operator "="
00442 
00443    if (this == &g) return *this;
00444 
00445    Clear();
00446 
00447    fNpoints = g.fNpoints;
00448    Build(fNpoints);
00449 
00450    for (Int_t n=0; n<fNpoints; n++) {
00451       fX[n] = g.fX[n];
00452       fY[n] = g.fY[n];
00453       fZ[n] = g.fZ[n];
00454    }
00455    return *this;
00456 }
00457 
00458 //______________________________________________________________________________
00459 void TGraph2D::Build(Int_t n)
00460 {
00461    // Creates the 2D graph basic data structure
00462 
00463    if (n <= 0) {
00464       Error("TGraph2D", "Invalid number of points (%d)", n);
00465       return;
00466    }
00467 
00468    fSize      = n;
00469    fMargin    = 0.;
00470    fNpx       = 40;
00471    fNpy       = 40;
00472    fDirectory = 0;
00473    fHistogram = 0;
00474    fMaximum   = -1111;
00475    fMinimum   = -1111;
00476    fX         = new Double_t[fSize];
00477    fY         = new Double_t[fSize];
00478    fZ         = new Double_t[fSize];
00479    fZout      = 0;
00480    fMaxIter   = 100000;
00481    fFunctions = new TList;
00482    fPainter   = 0;
00483    fUserHisto = kFALSE;
00484 
00485    if (TH1::AddDirectoryStatus()) {
00486       fDirectory = gDirectory;
00487       if (fDirectory) {
00488          fDirectory->Append(this,kTRUE);
00489       }
00490    }
00491 }
00492 
00493 
00494 //______________________________________________________________________________
00495 void TGraph2D::Clear(Option_t * /*option = "" */)
00496 {
00497    // Free all memory allocated by this object.
00498 
00499    delete [] fX; fX = 0;
00500    delete [] fY; fY = 0;
00501    delete [] fZ; fZ = 0;
00502    delete fHistogram; fHistogram = 0;
00503    if (fFunctions) {
00504       fFunctions->SetBit(kInvalidObject);
00505       fFunctions->Delete();
00506       delete fFunctions;
00507       fFunctions = 0;
00508    }
00509    if (fDirectory) {
00510       fDirectory->Remove(this);
00511       fDirectory = 0;
00512    }
00513    delete fPainter;
00514    fPainter   = 0;
00515 }
00516 
00517 
00518 //______________________________________________________________________________
00519 void TGraph2D::DirectoryAutoAdd(TDirectory *dir)
00520 {
00521    // Perform the automatic addition of the graph to the given directory
00522    //
00523    // Note this function is called in place when the semantic requires
00524    // this object to be added to a directory (I.e. when being read from
00525    // a TKey or being Cloned)
00526 
00527    Bool_t addStatus = TH1::AddDirectoryStatus();
00528    if (addStatus) {
00529       SetDirectory(dir);
00530       if (dir) {
00531          ResetBit(kCanDelete);
00532       }
00533    }
00534 }
00535 
00536 
00537 //______________________________________________________________________________
00538 Int_t TGraph2D::DistancetoPrimitive(Int_t px, Int_t py)
00539 {
00540    // Computes distance from point px,py to a graph
00541 
00542    Int_t distance = 9999;
00543    if (fHistogram) distance = fHistogram->DistancetoPrimitive(px,py);
00544    return distance;
00545 }
00546 
00547 
00548 //______________________________________________________________________________
00549 void TGraph2D::Draw(Option_t *option)
00550 {
00551    // Specific drawing options can be used to paint a TGraph2D:
00552    //
00553    //   "TRI"  : The Delaunay triangles are drawn using filled area.
00554    //            An hidden surface drawing technique is used. The surface is
00555    //            painted with the current fill area color. The edges of each
00556    //            triangles are painted with the current line color.
00557    //   "TRIW" : The Delaunay triangles are drawn as wire frame
00558    //   "TRI1" : The Delaunay triangles are painted with color levels. The edges
00559    //            of each triangles are painted with the current line color.
00560    //   "TRI2" : the Delaunay triangles are painted with color levels.
00561    //   "P"    : Draw a marker at each vertex
00562    //   "P0"   : Draw a circle at each vertex. Each circle background is white.
00563    //   "PCOL" : Draw a marker at each vertex. The color of each marker is
00564    //            defined according to its Z position.
00565    //   "CONT" : Draw contours
00566    //   "LINE" : Draw a 3D polyline
00567    //
00568    // A TGraph2D can be also drawn with ANY options valid to draw a 2D histogram.
00569    //
00570    // When a TGraph2D is drawn with one of the 2D histogram drawing option,
00571    // a intermediate 2D histogram is filled using the Delaunay triangles
00572    // technique to interpolate the data set.
00573 
00574    TString opt = option;
00575    opt.ToLower();
00576    if (gPad) {
00577       if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
00578       if (!opt.Contains("same")) {
00579          //the following statement is necessary in case one attempts to draw
00580          //a temporary histogram already in the current pad
00581          if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
00582          gPad->Clear();
00583       }
00584    }
00585    AppendPad(opt.Data());
00586 }
00587 
00588 
00589 //______________________________________________________________________________
00590 void TGraph2D::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00591 {
00592    // Executes action corresponding to one event
00593 
00594    if (fHistogram) fHistogram->ExecuteEvent(event, px, py);
00595 }
00596 
00597 
00598 //______________________________________________________________________________
00599 TObject *TGraph2D::FindObject(const char *name) const
00600 {
00601    // search object named name in the list of functions
00602 
00603    if (fFunctions) return fFunctions->FindObject(name);
00604    return 0;
00605 }
00606 
00607 
00608 //______________________________________________________________________________
00609 TObject *TGraph2D::FindObject(const TObject *obj) const
00610 {
00611    // search object obj in the list of functions
00612 
00613    if (fFunctions) return fFunctions->FindObject(obj);
00614    return 0;
00615 }
00616 
00617 
00618 //______________________________________________________________________________
00619 TFitResultPtr TGraph2D::Fit(const char *fname, Option_t *option, Option_t *)
00620 {
00621    // Fits this graph with function with name fname
00622    // Predefined functions such as gaus, expo and poln are automatically
00623    // created by ROOT.
00624    // fname can also be a formula, accepted by the linear fitter (linear parts divided
00625    // by "++" sign), for example "x++sin(y)" for fitting "[0]*x+[1]*sin(y)"
00626 
00627 
00628    char *linear;
00629    linear= (char*)strstr(fname, "++");
00630    TF2 *f2=0;
00631    if (linear)
00632       f2=new TF2(fname, fname);
00633    else{
00634       f2 = (TF2*)gROOT->GetFunction(fname);
00635       if (!f2) { Printf("Unknown function: %s",fname); return -1; }
00636    }
00637    return Fit(f2,option,"");
00638 
00639 }
00640 
00641 
00642 //______________________________________________________________________________
00643 TFitResultPtr TGraph2D::Fit(TF2 *f2, Option_t *option, Option_t *)
00644 {
00645    // Fits this 2D graph with function f2
00646    //
00647    //  f2 is an already predefined function created by TF2.
00648    //  Predefined functions such as gaus, expo and poln are automatically
00649    //  created by ROOT.
00650    //
00651    //  The list of fit options is given in parameter option.
00652    //     option = "W" Set all weights to 1; ignore error bars
00653    //            = "U" Use a User specified fitting algorithm (via SetFCN)
00654    //            = "Q" Quiet mode (minimum printing)
00655    //            = "V" Verbose mode (default is between Q and V)
00656    //            = "R" Use the Range specified in the function range
00657    //            = "N" Do not store the graphics function, do not draw
00658    //            = "0" Do not plot the result of the fit. By default the fitted function
00659    //                  is drawn unless the option "N" above is specified.
00660    //            = "+" Add this new fitted function to the list of fitted functions
00661    //                  (by default, any previous function is deleted)
00662    //            = "C" In case of linear fitting, not calculate the chisquare
00663    //                  (saves time)
00664    //            = "EX0" When fitting a TGraphErrors do not consider errors in the coordinate
00665    //            = "ROB" In case of linear fitting, compute the LTS regression
00666    //                     coefficients (robust (resistant) regression), using
00667    //                     the default fraction of good points
00668    //              "ROB=0.x" - compute the LTS regression coefficients, using
00669    //                           0.x as a fraction of good points
00670    //            = "S"  The result of the fit is returned in the TFitResultPtr
00671    //                     (see below Access to the Fit Result)
00672    //
00673    //  In order to use the Range option, one must first create a function
00674    //  with the expression to be fitted. For example, if your graph2d
00675    //  has a defined range between -4 and 4 and you want to fit a gaussian
00676    //  only in the interval 1 to 3, you can do:
00677    //       TF2 *f2 = new TF2("f2","gaus",1,3);
00678    //       graph2d->Fit("f2","R");
00679    //
00680    //
00681    //  Setting initial conditions
00682    //  ==========================
00683    //  Parameters must be initialized before invoking the Fit function.
00684    //  The setting of the parameter initial values is automatic for the
00685    //  predefined functions : poln, expo, gaus. One can however disable
00686    //  this automatic computation by specifying the option "B".
00687    //  You can specify boundary limits for some or all parameters via
00688    //       f2->SetParLimits(p_number, parmin, parmax);
00689    //  if parmin>=parmax, the parameter is fixed
00690    //  Note that you are not forced to fix the limits for all parameters.
00691    //  For example, if you fit a function with 6 parameters, you can do:
00692    //    func->SetParameters(0,3.1,1.e-6,0.1,-8,100);
00693    //    func->SetParLimits(4,-10,-4);
00694    //    func->SetParLimits(5, 1,1);
00695    //  With this setup, parameters 0->3 can vary freely
00696    //  Parameter 4 has boundaries [-10,-4] with initial value -8
00697    //  Parameter 5 is fixed to 100.
00698    //
00699    //  Fit range
00700    //  =========
00701    //  The fit range can be specified in two ways:
00702    //    - specify rxmax > rxmin (default is rxmin=rxmax=0)
00703    //    - specify the option "R". In this case, the function will be taken
00704    //      instead of the full graph range.
00705    //
00706    //  Changing the fitting function
00707    //  =============================
00708    //   By default a chi2 fitting function is used for fitting a TGraph.
00709    //   The function is implemented in FitUtil::EvaluateChi2.
00710    //   In case of TGraph2DErrors an effective chi2 is used
00711    //   (see TGraphErrors fit in TGraph::Fit) and is implemented in
00712    //   FitUtil::EvaluateChi2Effective
00713    //   To specify a User defined fitting function, specify option "U" and
00714    //   call the following functions:
00715    //   TVirtualFitter::Fitter(mygraph)->SetFCN(MyFittingFunction)
00716    //   where MyFittingFunction is of type:
00717    //   extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00718    //
00719    //  Associated functions
00720    //  ====================
00721    //  One or more object (typically a TF2*) can be added to the list
00722    //  of functions (fFunctions) associated to each graph.
00723    //  When TGraph::Fit is invoked, the fitted function is added to this list.
00724    //  Given a graph gr, one can retrieve an associated function
00725    //  with:  TF2 *myfunc = gr->GetFunction("myfunc");
00726    //
00727    //  Access to the fit results
00728    //  =========================
00729    //  The function returns a TFitResultPtr which can hold a  pointer to a TFitResult object.
00730    //  By default the TFitResultPtr contains only the status of the fit and it converts automatically to an
00731    //  integer. If the option "S" is instead used, TFitResultPtr contains the TFitResult and behaves as a smart
00732    //  pointer to it. For example one can do:
00733    //     TFitResultPtr r = graph->Fit("myFunc","S");
00734    //     TMatrixDSym cov = r->GetCovarianceMatrix();  //  to access the covariance matrix
00735    //     Double_t par0   = r->Value(0); // retrieve the value for the parameter 0
00736    //     Double_t err0   = r->Error(0); // retrieve the error for the parameter 0
00737    //     r->Print("V");     // print full information of fit including covariance matrix
00738    //     r->Write();        // store the result in a file
00739    //
00740    //  The fit parameters, error and chi2 (but not covariance matrix) can be retrieved also
00741    //  from the fitted function.
00742    //  If the graph is made persistent, the list of
00743    //  associated functions is also persistent. Given a pointer (see above)
00744    //  to an associated function myfunc, one can retrieve the function/fit
00745    //  parameters with calls such as:
00746    //    Double_t chi2 = myfunc->GetChisquare();
00747    //    Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
00748    //    Double_t err0 = myfunc->GetParError(0);  //error on first parameter
00749    //
00750    //  Fit Statistics
00751    //  ==============
00752    //  You can change the statistics box to display the fit parameters with
00753    //  the TStyle::SetOptFit(mode) method. This mode has four digits.
00754    //  mode = pcev  (default = 0111)
00755    //    v = 1;  print name/values of parameters
00756    //    e = 1;  print errors (if e=1, v must be 1)
00757    //    c = 1;  print Chisquare/Number of degress of freedom
00758    //    p = 1;  print Probability
00759    //
00760    //  For example: gStyle->SetOptFit(1011);
00761    //  prints the fit probability, parameter names/values, and errors.
00762    //  You can change the position of the statistics box with these lines
00763    //  (where g is a pointer to the TGraph):
00764    //
00765    //  Root > TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats")
00766    //  Root > st->SetX1NDC(newx1); //new x start position
00767    //  Root > st->SetX2NDC(newx2); //new x end position
00768 
00769    // internal graph2D fitting methods
00770    Foption_t fitOption;
00771    Option_t *goption = "";
00772    ROOT::Fit::FitOptionsMake(option,fitOption);
00773 
00774    // create range and minimizer options with default values
00775    ROOT::Fit::DataRange range(2);
00776    ROOT::Math::MinimizerOptions minOption;
00777    return ROOT::Fit::FitObject(this, f2 , fitOption , minOption, goption, range);
00778 }
00779 
00780 
00781 //______________________________________________________________________________
00782 void TGraph2D::FitPanel()
00783 {
00784    // Display a GUI panel with all graph fit options.
00785    //
00786    //   See class TFitEditor for example
00787    if (!gPad)
00788       gROOT->MakeDefCanvas();
00789 
00790    if (!gPad) {
00791       Error("FitPanel", "Unable to create a default canvas");
00792       return;
00793    }
00794 
00795    // use plugin manager to create instance of TFitEditor
00796    TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
00797    if (handler && handler->LoadPlugin() != -1) {
00798       if (handler->ExecPlugin(2, gPad, this) == 0)
00799          Error("FitPanel", "Unable to crate the FitPanel");
00800    }
00801    else
00802       Error("FitPanel", "Unable to find the FitPanel plug-in");
00803 
00804 }
00805 
00806 
00807 //______________________________________________________________________________
00808 TAxis *TGraph2D::GetXaxis() const
00809 {
00810    // Get x axis of the graph.
00811 
00812    //if (!gPad) return 0;
00813    TH1 *h = ((TGraph2D*)this)->GetHistogram();
00814    if (!h) return 0;
00815    return h->GetXaxis();
00816 }
00817 
00818 
00819 //______________________________________________________________________________
00820 TAxis *TGraph2D::GetYaxis() const
00821 {
00822    // Get y axis of the graph.
00823 
00824    //if (!gPad) return 0;
00825    TH1 *h = ((TGraph2D*)this)->GetHistogram();
00826    if (!h) return 0;
00827    return h->GetYaxis();
00828 }
00829 
00830 
00831 //______________________________________________________________________________
00832 TAxis *TGraph2D::GetZaxis() const
00833 {
00834    // Get z axis of the graph.
00835 
00836    //if (!gPad) return 0;
00837    TH1 *h = ((TGraph2D*)this)->GetHistogram();
00838    if (!h) return 0;
00839    return h->GetZaxis();
00840 }
00841 
00842 
00843 //______________________________________________________________________________
00844 TList *TGraph2D::GetContourList(Double_t contour)
00845 {
00846    // Returns the X and Y graphs building a contour. A contour level may
00847    // consist in several parts not connected to each other. This function
00848    // returns them in a graphs' list.
00849 
00850    if (fNpoints <= 0) {
00851       Error("GetContourList", "Empty TGraph2D");
00852       return 0;
00853    }
00854 
00855    if(!fHistogram) GetHistogram("empty");
00856 
00857    if (!fPainter) fPainter = fHistogram->GetPainter();
00858 
00859    return fPainter->GetContourList(contour);
00860 }
00861 
00862 
00863 //______________________________________________________________________________
00864 Double_t TGraph2D::GetErrorX(Int_t) const
00865 {
00866    // This function is called by Graph2DFitChisquare.
00867    // It always returns a negative value. Real implementation in TGraph2DErrors
00868 
00869    return -1;
00870 }
00871 
00872 
00873 //______________________________________________________________________________
00874 Double_t TGraph2D::GetErrorY(Int_t) const
00875 {
00876    // This function is called by Graph2DFitChisquare.
00877    // It always returns a negative value. Real implementation in TGraph2DErrors
00878 
00879    return -1;
00880 }
00881 
00882 
00883 //______________________________________________________________________________
00884 Double_t TGraph2D::GetErrorZ(Int_t) const
00885 {
00886    // This function is called by Graph2DFitChisquare.
00887    // It always returns a negative value. Real implementation in TGraph2DErrors
00888 
00889    return -1;
00890 }
00891 
00892 
00893 //______________________________________________________________________________
00894 TH2D *TGraph2D::GetHistogram(Option_t *option)
00895 {
00896    // By default returns a pointer to the Delaunay histogram. If fHistogram
00897    // doesn't exist, books the 2D histogram fHistogram with a margin around
00898    // the hull. Calls TGraphDelaunay::Interpolate at each bin centre to build up
00899    // an interpolated 2D histogram.
00900    // If the "empty" option is selected, returns an empty histogram booked with
00901    // the limits of fX, fY and fZ. This option is used when the data set is
00902    // drawn with markers only. In that particular case there is no need to
00903    // find the Delaunay triangles.
00904 
00905    if (fNpoints <= 0) {
00906       Error("GetHistogram", "Empty TGraph2D");
00907       return 0;
00908    }
00909 
00910    TString opt = option;
00911    opt.ToLower();
00912    Bool_t empty = opt.Contains("empty");
00913 
00914    if (fHistogram) {
00915       if (!empty && fHistogram->GetEntries()==0) {
00916          if (!fUserHisto) {
00917             delete fHistogram;
00918             fHistogram = 0;
00919          }
00920       } else {
00921          return fHistogram;
00922       }
00923    }
00924 
00925    Double_t hxmax, hymax, hxmin, hymin;
00926 
00927    // Book fHistogram if needed. It is not added in the current directory
00928    if (!fUserHisto) {
00929       Bool_t add = TH1::AddDirectoryStatus();
00930       TH1::AddDirectory(kFALSE);
00931       Double_t xmax  = GetXmaxE();
00932       Double_t ymax  = GetYmaxE();
00933       Double_t xmin  = GetXminE();
00934       Double_t ymin  = GetYminE();
00935       hxmin = xmin-fMargin*(xmax-xmin);
00936       hymin = ymin-fMargin*(ymax-ymin);
00937       hxmax = xmax+fMargin*(xmax-xmin);
00938       hymax = ymax+fMargin*(ymax-ymin);
00939       fHistogram = new TH2D(GetName(),GetTitle(),
00940                             fNpx ,hxmin, hxmax,
00941                             fNpy, hymin, hymax);
00942       TH1::AddDirectory(add);
00943       fHistogram->SetBit(TH1::kNoStats);
00944    } else {
00945       hxmin = fHistogram->GetXaxis()->GetXmin();
00946       hymin = fHistogram->GetYaxis()->GetXmin();
00947       hxmax = fHistogram->GetXaxis()->GetXmax();
00948       hymax = fHistogram->GetYaxis()->GetXmax();
00949    }
00950 
00951    // Add a TGraphDelaunay in the list of the fHistogram's functions
00952    TGraphDelaunay *dt = new TGraphDelaunay(this);
00953    dt->SetMaxIter(fMaxIter);
00954    dt->SetMarginBinsContent(fZout);
00955    TList *hl = fHistogram->GetListOfFunctions();
00956    hl->Add(dt);
00957 
00958    // Option "empty" is selected. An empty histogram is returned.
00959    if (empty) {
00960       Double_t hzmax, hzmin;
00961       if (fMinimum != -1111) {
00962          hzmin = fMinimum;
00963       } else {
00964          hzmin = GetZmin();
00965 ///         hzmin = GetZminE();
00966       }
00967       if (fMaximum != -1111) {
00968          hzmax = fMaximum;
00969       } else {
00970          hzmax = GetZmax();
00971 ///         hzmax = GetZmaxE();
00972       }
00973       if (hzmin==hzmax) {
00974          hzmin = hzmin-0.01*hzmin;
00975          hzmax = hzmax+0.01*hzmax;
00976       }
00977       fHistogram->SetMinimum(hzmin);
00978       fHistogram->SetMaximum(hzmax);
00979       return fHistogram;
00980    }
00981 
00982    Double_t dx = (hxmax-hxmin)/fNpx;
00983    Double_t dy = (hymax-hymin)/fNpy;
00984 
00985    Double_t x, y, z;
00986    for (Int_t ix=1; ix<=fNpx; ix++) {
00987       x  = hxmin+(ix-0.5)*dx;
00988       for (Int_t iy=1; iy<=fNpy; iy++) {
00989          y  = hymin+(iy-0.5)*dy;
00990          z  = dt->ComputeZ(x, y);
00991          fHistogram->Fill(x, y, z);
00992       }
00993    }
00994 
00995    if (fMinimum != -1111) fHistogram->SetMinimum(fMinimum);
00996    if (fMaximum != -1111) fHistogram->SetMaximum(fMaximum);
00997 
00998    return fHistogram;
00999 }
01000 
01001 
01002 //______________________________________________________________________________
01003 Double_t TGraph2D::GetXmax() const
01004 {
01005    // Returns the X maximum
01006 
01007    Double_t v = fX[0];
01008    for (Int_t i=1; i<fNpoints; i++) if (fX[i]>v) v=fX[i];
01009    return v;
01010 }
01011 
01012 
01013 //______________________________________________________________________________
01014 Double_t TGraph2D::GetXmin() const
01015 {
01016    // Returns the X minimum
01017 
01018    Double_t v = fX[0];
01019    for (Int_t i=1; i<fNpoints; i++) if (fX[i]<v) v=fX[i];
01020    return v;
01021 }
01022 
01023 
01024 //______________________________________________________________________________
01025 Double_t TGraph2D::GetYmax() const
01026 {
01027    // Returns the Y maximum
01028 
01029    Double_t v = fY[0];
01030    for (Int_t i=1; i<fNpoints; i++) if (fY[i]>v) v=fY[i];
01031    return v;
01032 }
01033 
01034 
01035 //______________________________________________________________________________
01036 Double_t TGraph2D::GetYmin() const
01037 {
01038    // Returns the Y minimum
01039 
01040    Double_t v = fY[0];
01041    for (Int_t i=1; i<fNpoints; i++) if (fY[i]<v) v=fY[i];
01042    return v;
01043 }
01044 
01045 
01046 //______________________________________________________________________________
01047 Double_t TGraph2D::GetZmax() const
01048 {
01049    // Returns the Z maximum
01050 
01051    Double_t v = fZ[0];
01052    for (Int_t i=1; i<fNpoints; i++) if (fZ[i]>v) v=fZ[i];
01053    return v;
01054 }
01055 
01056 
01057 //______________________________________________________________________________
01058 Double_t TGraph2D::GetZmin() const
01059 {
01060    // Returns the Z minimum
01061 
01062    Double_t v = fZ[0];
01063    for (Int_t i=1; i<fNpoints; i++) if (fZ[i]<v) v=fZ[i];
01064    return v;
01065 }
01066 
01067 
01068 //______________________________________________________________________________
01069 Double_t TGraph2D::Interpolate(Double_t x, Double_t y)
01070 {
01071    // Finds the z value at the position (x,y) thanks to
01072    // the Delaunay interpolation.
01073 
01074    if (fNpoints <= 0) {
01075       Error("Interpolate", "Empty TGraph2D");
01076       return 0;
01077    }
01078 
01079    TGraphDelaunay *dt;
01080 
01081    if(!fHistogram) GetHistogram("empty");
01082 
01083    TList *hl = fHistogram->GetListOfFunctions();
01084    dt = (TGraphDelaunay*)hl->FindObject("TGraphDelaunay");
01085 
01086    return dt->ComputeZ(x, y);
01087 }
01088 
01089 
01090 //______________________________________________________________________________
01091 void TGraph2D::Paint(Option_t *option)
01092 {
01093    // Paints this 2D graph with its current attributes
01094 
01095    if (fNpoints <= 0) {
01096       Error("Paint", "Empty TGraph2D");
01097       return;
01098    }
01099 
01100    TString opt = option;
01101    opt.ToLower();
01102    if (opt.Contains("p") && !opt.Contains("tri")) {
01103       if (!opt.Contains("pol") &&
01104           !opt.Contains("sph") &&
01105           !opt.Contains("psr")) opt.Append("tri0");
01106    }
01107 
01108    if (opt.Contains("line") && !opt.Contains("tri")) opt.Append("tri0");
01109 
01110    if (opt.Contains("err")  && !opt.Contains("tri")) opt.Append("tri0");
01111 
01112    if (opt.Contains("tri0")) {
01113       GetHistogram("empty");
01114    } else {
01115       GetHistogram();
01116    }
01117 
01118    fHistogram->SetLineColor(GetLineColor());
01119    fHistogram->SetLineStyle(GetLineStyle());
01120    fHistogram->SetLineWidth(GetLineWidth());
01121    fHistogram->SetFillColor(GetFillColor());
01122    fHistogram->SetFillStyle(GetFillStyle());
01123    fHistogram->SetMarkerColor(GetMarkerColor());
01124    fHistogram->SetMarkerStyle(GetMarkerStyle());
01125    fHistogram->SetMarkerSize(GetMarkerSize());
01126    fHistogram->Paint(opt.Data());
01127 }
01128 
01129 
01130 //______________________________________________________________________________
01131 TH1 *TGraph2D::Project(Option_t *option) const
01132 {
01133    // Projects a 2-d graph into 1 or 2-d histograms depending on the
01134    // option parameter
01135    // option may contain a combination of the characters x,y,z
01136    // option = "x" return the x projection into a TH1D histogram
01137    // option = "y" return the y projection into a TH1D histogram
01138    // option = "xy" return the x versus y projection into a TH2D histogram
01139    // option = "yx" return the y versus x projection into a TH2D histogram
01140 
01141    if (fNpoints <= 0) {
01142       Error("Project", "Empty TGraph2D");
01143       return 0;
01144    }
01145 
01146    TString opt = option; opt.ToLower();
01147 
01148    Int_t pcase = 0;
01149    if (opt.Contains("x"))  pcase = 1;
01150    if (opt.Contains("y"))  pcase = 2;
01151    if (opt.Contains("xy")) pcase = 3;
01152    if (opt.Contains("yx")) pcase = 4;
01153 
01154    // Create the projection histogram
01155    TH1D *h1 = 0;
01156    TH2D *h2 = 0;
01157    Int_t nch = strlen(GetName()) +opt.Length() +2;
01158    char *name = new char[nch];
01159    snprintf(name,nch,"%s_%s",GetName(),option);
01160    nch = strlen(GetTitle()) +opt.Length() +2;
01161    char *title = new char[nch];
01162    snprintf(title,nch,"%s_%s",GetTitle(),option);
01163 
01164    Double_t hxmin = GetXmin();
01165    Double_t hxmax = GetXmax();
01166    Double_t hymin = GetYmin();
01167    Double_t hymax = GetYmax();
01168 
01169    switch (pcase) {
01170       case 1:
01171          // "x"
01172          h1 = new TH1D(name,title,fNpx,hxmin,hxmax);
01173          break;
01174       case 2:
01175          // "y"
01176          h1 = new TH1D(name,title,fNpy,hymin,hymax);
01177          break;
01178       case 3:
01179          // "xy"
01180          h2 = new TH2D(name,title,fNpx,hxmin,hxmax,fNpy,hymin,hymax);
01181          break;
01182       case 4:
01183          // "yx"
01184          h2 = new TH2D(name,title,fNpy,hymin,hymax,fNpx,hxmin,hxmax);
01185          break;
01186    }
01187 
01188    delete [] name;
01189    delete [] title;
01190    TH1 *h = h1;
01191    if (h2) h = h2;
01192    if (h == 0) return 0;
01193 
01194    // Fill the projected histogram
01195    Double_t entries = 0;
01196    for (Int_t n=0; n<fNpoints; n++) {
01197       switch (pcase) {
01198          case 1:
01199             // "x"
01200             h1->Fill(fX[n], fZ[n]);
01201             break;
01202          case 2:
01203             // "y"
01204             h1->Fill(fY[n], fZ[n]);
01205             break;
01206          case 3:
01207             // "xy"
01208             h2->Fill(fX[n], fY[n], fZ[n]);
01209             break;
01210          case 4:
01211             // "yx"
01212             h2->Fill(fY[n], fX[n], fZ[n]);
01213             break;
01214       }
01215       entries += fZ[n];
01216    }
01217    h->SetEntries(entries);
01218    return h;
01219 }
01220 
01221 
01222 //______________________________________________________________________________
01223 Int_t TGraph2D::RemovePoint(Int_t ipoint)
01224 {
01225    // Deletes point number ipoint
01226 
01227    if (ipoint < 0) return -1;
01228    if (ipoint >= fNpoints) return -1;
01229 
01230    fNpoints--;
01231    Double_t *newX = new Double_t[fNpoints];
01232    Double_t *newY = new Double_t[fNpoints];
01233    Double_t *newZ = new Double_t[fNpoints];
01234    Int_t j = -1;
01235    for (Int_t i=0;i<fNpoints+1;i++) {
01236       if (i == ipoint) continue;
01237       j++;
01238       newX[j] = fX[i];
01239       newY[j] = fY[i];
01240       newZ[j] = fZ[i];
01241    }
01242    delete [] fX;
01243    delete [] fY;
01244    delete [] fZ;
01245    fX = newX;
01246    fY = newY;
01247    fZ = newZ;
01248    fSize = fNpoints;
01249    if (fHistogram) {delete fHistogram; fHistogram = 0;}
01250    return ipoint;
01251 }
01252 
01253 
01254 //______________________________________________________________________________
01255 void TGraph2D::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
01256 {
01257    // Saves primitive as a C++ statement(s) on output stream out
01258 
01259    char quote = '"';
01260    out<<"   "<<endl;
01261    if (gROOT->ClassSaved(TGraph2D::Class())) {
01262       out<<"   ";
01263    } else {
01264       out<<"   TGraph2D *";
01265    }
01266 
01267    out<<"graph2d = new TGraph2D("<<fNpoints<<");"<<endl;
01268    out<<"   graph2d->SetName("<<quote<<GetName()<<quote<<");"<<endl;
01269    out<<"   graph2d->SetTitle("<<quote<<GetTitle()<<quote<<");"<<endl;
01270 
01271    if (fDirectory == 0) {
01272       out<<"   "<<GetName()<<"->SetDirectory(0);"<<endl;
01273    }
01274 
01275    SaveFillAttributes(out,"graph2d",0,1001);
01276    SaveLineAttributes(out,"graph2d",1,1,1);
01277    SaveMarkerAttributes(out,"graph2d",1,1,1);
01278 
01279    for (Int_t i=0;i<fNpoints;i++) {
01280       out<<"   graph2d->SetPoint("<<i<<","<<fX[i]<<","<<fY[i]<<","<<fZ[i]<<");"<<endl;
01281    }
01282 
01283    // save list of functions
01284    TIter next(fFunctions);
01285    TObject *obj;
01286    while ((obj=next())) {
01287       obj->SavePrimitive(out,"nodraw");
01288       out<<"   graph2d->GetListOfFunctions()->Add("<<obj->GetName()<<");"<<endl;
01289       if (obj->InheritsFrom("TPaveStats")) {
01290          out<<"   ptstats->SetParent(graph2d->GetListOfFunctions());"<<endl;
01291       }
01292    }
01293 
01294    out<<"   graph2d->Draw("<<quote<<option<<quote<<");"<<endl;
01295 }
01296 
01297 
01298 //______________________________________________________________________________
01299 void TGraph2D::Set(Int_t n)
01300 {
01301    // Set number of points in the 2D graph.
01302    // Existing coordinates are preserved.
01303    // New coordinates above fNpoints are preset to 0.
01304 
01305    if (n < 0) n = 0;
01306    if (n == fNpoints) return;
01307    if (n >  fNpoints) SetPoint(n,0,0,0);
01308    fNpoints = n;
01309 }
01310 
01311 
01312 //______________________________________________________________________________
01313 void TGraph2D::SetDirectory(TDirectory *dir)
01314 {
01315    // By default when an 2D graph is created, it is added to the list
01316    // of 2D graph objects in the current directory in memory.
01317    // Remove reference to this 2D graph from current directory and add
01318    // reference to new directory dir. dir can be 0 in which case the
01319    // 2D graph does not belong to any directory.
01320 
01321    if (fDirectory == dir) return;
01322    if (fDirectory) fDirectory->Remove(this);
01323    fDirectory = dir;
01324    if (fDirectory) fDirectory->Append(this);
01325 }
01326 
01327 
01328 //______________________________________________________________________________
01329 void TGraph2D::SetHistogram(TH2 *h)
01330 {
01331    // Sets the histogram to be filled
01332 
01333    fUserHisto = kTRUE;
01334    fHistogram = (TH2D*)h;
01335    fNpx       = h->GetNbinsX();
01336    fNpy       = h->GetNbinsY();
01337 }
01338 
01339 
01340 //______________________________________________________________________________
01341 void TGraph2D::SetMargin(Double_t m)
01342 {
01343    // Sets the extra space (in %) around interpolated area for the 2D histogram
01344 
01345    if (m<0 || m>1) {
01346       Warning("SetMargin","The margin must be >= 0 && <= 1, fMargin set to 0.1");
01347       fMargin = 0.1;
01348    } else {
01349       fMargin = m;
01350    }
01351    if (fHistogram) {delete fHistogram; fHistogram = 0;}
01352 }
01353 
01354 
01355 //______________________________________________________________________________
01356 void TGraph2D::SetMarginBinsContent(Double_t z)
01357 {
01358    // Sets the histogram bin height for points lying outside the TGraphDelaunay
01359    // convex hull ie: the bins in the margin.
01360 
01361    fZout = z;
01362    if (fHistogram) {delete fHistogram; fHistogram = 0;}
01363 }
01364 
01365 
01366 //______________________________________________________________________________
01367 void TGraph2D::SetMaximum(Double_t maximum)
01368 {
01369    // Set maximum.
01370 
01371    fMaximum = maximum;
01372    GetHistogram()->SetMaximum(maximum);
01373 }
01374 
01375 
01376 //______________________________________________________________________________
01377 void TGraph2D::SetMinimum(Double_t minimum)
01378 {
01379    // Set minimum.
01380 
01381    fMinimum = minimum;
01382    GetHistogram()->SetMinimum(minimum);
01383 }
01384 
01385 
01386 //______________________________________________________________________________
01387 void TGraph2D::SetName(const char *name)
01388 {
01389    // Changes the name of this 2D graph
01390 
01391    //  2D graphs are named objects in a THashList.
01392    //  We must update the hashlist if we change the name
01393    if (fDirectory) fDirectory->Remove(this);
01394    fName = name;
01395    if (fDirectory) fDirectory->Append(this);
01396 }
01397 
01398 
01399 //______________________________________________________________________________
01400 void TGraph2D::SetNameTitle(const char *name, const char *title)
01401 {
01402    // Change the name and title of this 2D graph
01403    //
01404 
01405    //  2D graphs are named objects in a THashList.
01406    //  We must update the hashlist if we change the name
01407    if (fDirectory) fDirectory->Remove(this);
01408    fName  = name;
01409    SetTitle(title);
01410    if (fDirectory) fDirectory->Append(this);
01411 }
01412 
01413 
01414 //______________________________________________________________________________
01415 void TGraph2D::SetNpx(Int_t npx)
01416 {
01417    // Sets the number of bins along X used to draw the function
01418 
01419    if (npx < 4) {
01420       Warning("SetNpx","Number of points must be >4 && < 500, fNpx set to 4");
01421       fNpx = 4;
01422    } else if(npx > 500) {
01423       Warning("SetNpx","Number of points must be >4 && < 500, fNpx set to 500");
01424       fNpx = 500;
01425    } else {
01426       fNpx = npx;
01427    }
01428    if (fHistogram) {delete fHistogram; fHistogram = 0;}
01429 }
01430 
01431 
01432 //______________________________________________________________________________
01433 void TGraph2D::SetNpy(Int_t npy)
01434 {
01435    // Sets the number of bins along Y used to draw the function
01436 
01437    if (npy < 4) {
01438       Warning("SetNpy","Number of points must be >4 && < 500, fNpy set to 4");
01439       fNpy = 4;
01440    } else if(npy > 500) {
01441       Warning("SetNpy","Number of points must be >4 && < 500, fNpy set to 500");
01442       fNpy = 500;
01443    } else {
01444       fNpy = npy;
01445    }
01446    if (fHistogram) {delete fHistogram; fHistogram = 0;}
01447 }
01448 
01449 
01450 //______________________________________________________________________________
01451 void TGraph2D::SetPoint(Int_t n, Double_t x, Double_t y, Double_t z)
01452 {
01453    // Sets point number n.
01454    // If n is greater than the current size, the arrays are automatically
01455    // extended.
01456 
01457    if (n < 0) return;
01458 
01459    if (!fX || !fY || !fZ || n >= fSize) {
01460    // re-allocate the object
01461       Int_t newN = TMath::Max(2*fSize,n+1);
01462       Double_t *savex = new Double_t [newN];
01463       Double_t *savey = new Double_t [newN];
01464       Double_t *savez = new Double_t [newN];
01465       if (fX && fSize) {
01466          memcpy(savex,fX,fSize*sizeof(Double_t));
01467          memset(&savex[fSize],0,(newN-fSize)*sizeof(Double_t));
01468          delete [] fX;
01469       }
01470       if (fY && fSize) {
01471          memcpy(savey,fY,fSize*sizeof(Double_t));
01472          memset(&savey[fSize],0,(newN-fSize)*sizeof(Double_t));
01473          delete [] fY;
01474       }
01475       if (fZ && fSize) {
01476          memcpy(savez,fZ,fSize*sizeof(Double_t));
01477          memset(&savez[fSize],0,(newN-fSize)*sizeof(Double_t));
01478          delete [] fZ;
01479       }
01480       fX    = savex;
01481       fY    = savey;
01482       fZ    = savez;
01483       fSize = newN;
01484    }
01485    fX[n]    = x;
01486    fY[n]    = y;
01487    fZ[n]    = z;
01488    fNpoints = TMath::Max(fNpoints,n+1);
01489 }
01490 
01491 
01492 //______________________________________________________________________________
01493 void TGraph2D::SetTitle(const char* title)
01494 {
01495    // Sets graph title
01496 
01497    fTitle = title;
01498    if (fHistogram) fHistogram->SetTitle(title);
01499 }
01500 
01501 
01502 //_______________________________________________________________________
01503 void TGraph2D::Streamer(TBuffer &b)
01504 {
01505    // Stream a class object
01506 
01507    if (b.IsReading()) {
01508       UInt_t R__s, R__c;
01509       Version_t R__v = b.ReadVersion(&R__s, &R__c);
01510       b.ReadClassBuffer(TGraph2D::Class(), this, R__v, R__s, R__c);
01511 
01512       ResetBit(kMustCleanup);
01513    } else {
01514       b.WriteClassBuffer(TGraph2D::Class(),this);
01515    }
01516 }

Generated on Tue Jul 5 14:24:18 2011 for ROOT_528-00b_version by  doxygen 1.5.1