Logo ROOT  
Reference Guide
TGraphErrors.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Rene Brun 15/09/96
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 
13 #include "TROOT.h"
14 #include "TBuffer.h"
15 #include "TGraphErrors.h"
16 #include "TStyle.h"
17 #include "TMath.h"
18 #include "TVirtualPad.h"
19 #include "TH1.h"
20 #include "TF1.h"
21 #include "TVectorD.h"
22 #include "TSystem.h"
23 #include "strtok.h"
24 
25 #include <iostream>
26 #include <fstream>
27 #include <cstring>
28 #include <string>
29 
31 
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 
35 /** \class TGraphErrors
36  \ingroup Hist
37 A TGraphErrors is a TGraph with error bars.
38 
39 The TGraphErrors painting is performed thanks to the TGraphPainter
40 class. All details about the various painting options are given in this class.
41 
42 The picture below gives an example:
43 
44 Begin_Macro(source)
45 {
46  auto c1 = new TCanvas("c1","A Simple Graph with error bars",200,10,700,500);
47  c1->SetFillColor(42);
48  c1->SetGrid();
49  c1->GetFrame()->SetFillColor(21);
50  c1->GetFrame()->SetBorderSize(12);
51  const Int_t n = 10;
52  Double_t x[n] = {-0.22, 0.05, 0.25, 0.35, 0.5, 0.61,0.7,0.85,0.89,0.95};
53  Double_t y[n] = {1,2.9,5.6,7.4,9,9.6,8.7,6.3,4.5,1};
54  Double_t ex[n] = {.05,.1,.07,.07,.04,.05,.06,.07,.08,.05};
55  Double_t ey[n] = {.8,.7,.6,.5,.4,.4,.5,.6,.7,.8};
56  auto gr = new TGraphErrors(n,x,y,ex,ey);
57  gr->SetTitle("TGraphErrors Example");
58  gr->SetMarkerColor(4);
59  gr->SetMarkerStyle(21);
60  gr->Draw("ALP");
61 }
62 End_Macro
63 */
64 
65 
66 ////////////////////////////////////////////////////////////////////////////////
67 /// TGraphErrors default constructor.
68 
70 {
71  if (!CtorAllocate()) return;
72 }
73 
74 
75 ////////////////////////////////////////////////////////////////////////////////
76 /// TGraphErrors normal constructor.
77 ///
78 /// the arrays are preset to zero
79 
81  : TGraph(n)
82 {
83  if (!CtorAllocate()) return;
84  FillZero(0, fNpoints);
85 }
86 
87 
88 ////////////////////////////////////////////////////////////////////////////////
89 /// TGraphErrors normal constructor.
90 ///
91 /// if ex or ey are null, the corresponding arrays are preset to zero
92 
94  : TGraph(n, x, y)
95 {
96  if (!CtorAllocate()) return;
97 
98  for (Int_t i = 0; i < n; i++) {
99  if (ex) fEX[i] = ex[i];
100  else fEX[i] = 0;
101  if (ey) fEY[i] = ey[i];
102  else fEY[i] = 0;
103  }
104 }
105 
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 /// TGraphErrors normal constructor.
109 ///
110 /// if ex or ey are null, the corresponding arrays are preset to zero
111 
113  : TGraph(n, x, y)
114 {
115  if (!CtorAllocate()) return;
116 
117  n = sizeof(Double_t) * fNpoints;
118  if (ex) memcpy(fEX, ex, n);
119  else memset(fEX, 0, n);
120  if (ey) memcpy(fEY, ey, n);
121  else memset(fEY, 0, n);
122 }
123 
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 /// constructor with four vectors of floats in input
127 /// A grapherrors is built with the X coordinates taken from vx and Y coord from vy
128 /// and the errors from vectors vex and vey.
129 /// The number of points in the graph is the minimum of number of points
130 /// in vx and vy.
131 
132 TGraphErrors::TGraphErrors(const TVectorF &vx, const TVectorF &vy, const TVectorF &vex, const TVectorF &vey)
133  : TGraph(TMath::Min(vx.GetNrows(), vy.GetNrows()), vx.GetMatrixArray(), vy.GetMatrixArray() )
134 {
135  if (!CtorAllocate()) return;
136  Int_t ivexlow = vex.GetLwb();
137  Int_t iveylow = vey.GetLwb();
138  for (Int_t i = 0; i < fNpoints; i++) {
139  fEX[i] = vex(i + ivexlow);
140  fEY[i] = vey(i + iveylow);
141  }
142 }
143 
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 /// constructor with four vectors of doubles in input
147 /// A grapherrors is built with the X coordinates taken from vx and Y coord from vy
148 /// and the errors from vectors vex and vey.
149 /// The number of points in the graph is the minimum of number of points
150 /// in vx and vy.
151 
152 TGraphErrors::TGraphErrors(const TVectorD &vx, const TVectorD &vy, const TVectorD &vex, const TVectorD &vey)
153  : TGraph(TMath::Min(vx.GetNrows(), vy.GetNrows()), vx.GetMatrixArray(), vy.GetMatrixArray() )
154 {
155  if (!CtorAllocate()) return;
156  Int_t ivexlow = vex.GetLwb();
157  Int_t iveylow = vey.GetLwb();
158  for (Int_t i = 0; i < fNpoints; i++) {
159  fEX[i] = vex(i + ivexlow);
160  fEY[i] = vey(i + iveylow);
161  }
162 }
163 
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 /// TGraphErrors copy constructor
167 
169  : TGraph(gr)
170 {
171  if (!CtorAllocate()) return;
172 
173  Int_t n = sizeof(Double_t) * fNpoints;
174  memcpy(fEX, gr.fEX, n);
175  memcpy(fEY, gr.fEY, n);
176 }
177 
178 
179 ////////////////////////////////////////////////////////////////////////////////
180 /// TGraphErrors assignment operator
181 
183 {
184  if (this != &gr) {
186  // N.B CtorAllocate does not delete arrays
187  if (fEX) delete [] fEX;
188  if (fEY) delete [] fEY;
189  if (!CtorAllocate()) return *this;
190 
191  Int_t n = sizeof(Double_t) * fNpoints;
192  memcpy(fEX, gr.fEX, n);
193  memcpy(fEY, gr.fEY, n);
194  }
195  return *this;
196 }
197 
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 /// TGraphErrors constructor importing its parameters from the TH1 object passed as argument
201 
203  : TGraph(h)
204 {
205  if (!CtorAllocate()) return;
206 
207  for (Int_t i = 0; i < fNpoints; i++) {
208  fEX[i] = h->GetBinWidth(i + 1) * gStyle->GetErrorX();
209  fEY[i] = h->GetBinError(i + 1);
210  }
211 }
212 
213 
214 ////////////////////////////////////////////////////////////////////////////////
215 /// GraphErrors constructor reading input from filename
216 /// filename is assumed to contain at least 2 columns of numbers
217 ///
218 /// Convention for format (default="%lg %lg %lg %lg)
219 /// - format = "%lg %lg" read only 2 first columns into X,Y
220 /// - format = "%lg %lg %lg" read only 3 first columns into X,Y and EY
221 /// - format = "%lg %lg %lg %lg" read only 4 first columns into X,Y,EX,EY.
222 ///
223 /// For files separated by a specific delimiter different from ' ' and '\t' (e.g. ';' in csv files)
224 /// you can avoid using %*s to bypass this delimiter by explicitly specify the "option" argument,
225 /// e.g. option=" \t,;" for columns of figures separated by any of these characters (' ', '\t', ',', ';')
226 /// used once (e.g. "1;1") or in a combined way (" 1;,;; 1").
227 /// Note in that case, the instantiation is about 2 times slower.
228 /// In case a delimiter is specified, the format "%lg %lg %lg" will read X,Y,EX.
229 
230 TGraphErrors::TGraphErrors(const char *filename, const char *format, Option_t *option)
231  : TGraph(100)
232 {
233  if (!CtorAllocate()) return;
234  Double_t x, y, ex, ey;
235  TString fname = filename;
236  gSystem->ExpandPathName(fname);
237  std::ifstream infile(fname.Data());
238  if (!infile.good()) {
239  MakeZombie();
240  Error("TGraphErrors", "Cannot open file: %s, TGraphErrors is Zombie", filename);
241  fNpoints = 0;
242  return;
243  }
244  std::string line;
245  Int_t np = 0;
246 
247  if (strcmp(option, "") == 0) { // No delimiters specified (standard constructor).
248 
249  Int_t ncol = CalculateScanfFields(format); //count number of columns in format
250  Int_t res;
251  while (std::getline(infile, line, '\n')) {
252  ex = ey = 0;
253  if (ncol < 3) {
254  res = sscanf(line.c_str(), format, &x, &y);
255  } else if (ncol < 4) {
256  res = sscanf(line.c_str(), format, &x, &y, &ey);
257  } else {
258  res = sscanf(line.c_str(), format, &x, &y, &ex, &ey);
259  }
260  if (res < 2) {
261  continue; //skip empty and ill-formed lines
262  }
263  SetPoint(np, x, y);
264  SetPointError(np, ex, ey);
265  np++;
266  }
267  Set(np);
268 
269  } else { // A delimiter has been specified in "option"
270 
271  // Checking format and creating its boolean equivalent
272  TString format_ = TString(format) ;
273  format_.ReplaceAll(" ", "") ;
274  format_.ReplaceAll("\t", "") ;
275  format_.ReplaceAll("lg", "") ;
276  format_.ReplaceAll("s", "") ;
277  format_.ReplaceAll("%*", "0") ;
278  format_.ReplaceAll("%", "1") ;
279  if (!format_.IsDigit()) {
280  Error("TGraphErrors", "Incorrect input format! Allowed format tags are {\"%%lg\",\"%%*lg\" or \"%%*s\"}");
281  return ;
282  }
283  Int_t ntokens = format_.Length() ;
284  if (ntokens < 2) {
285  Error("TGraphErrors", "Incorrect input format! Only %d tag(s) in format whereas at least 2 \"%%lg\" tags are expected!", ntokens);
286  return ;
287  }
288  Int_t ntokensToBeSaved = 0 ;
289  Bool_t * isTokenToBeSaved = new Bool_t [ntokens] ;
290  for (Int_t idx = 0; idx < ntokens; idx++) {
291  isTokenToBeSaved[idx] = TString::Format("%c", format_[idx]).Atoi() ; //atoi(&format_[idx]) does not work for some reason...
292  if (isTokenToBeSaved[idx] == 1) {
293  ntokensToBeSaved++ ;
294  }
295  }
296  if (ntokens >= 2 && (ntokensToBeSaved < 2 || ntokensToBeSaved > 4)) { //first condition not to repeat the previous error message
297  Error("TGraphErrors", "Incorrect input format! There are %d \"%%lg\" tag(s) in format whereas 2,3 or 4 are expected!", ntokensToBeSaved);
298  delete [] isTokenToBeSaved ;
299  return ;
300  }
301 
302  // Initializing loop variables
303  Bool_t isLineToBeSkipped = kFALSE ; //empty and ill-formed lines
304  char * token = NULL ;
305  TString token_str = "" ;
306  Int_t token_idx = 0 ;
307  Double_t * value = new Double_t [4] ; //x,y,ex,ey buffers
308  for (Int_t k = 0; k < 4; k++) {
309  value[k] = 0. ;
310  }
311  Int_t value_idx = 0 ;
312 
313  // Looping
314  char *rest;
315  while (std::getline(infile, line, '\n')) {
316  if (line != "") {
317  if (line[line.size() - 1] == char(13)) { // removing DOS CR character
318  line.erase(line.end() - 1, line.end()) ;
319  }
320  token = R__STRTOK_R(const_cast<char *>(line.c_str()), option, &rest);
321  while (token != NULL && value_idx < ntokensToBeSaved) {
322  if (isTokenToBeSaved[token_idx]) {
323  token_str = TString(token) ;
324  token_str.ReplaceAll("\t", "") ;
325  if (!token_str.IsFloat()) {
326  isLineToBeSkipped = kTRUE ;
327  break ;
328  } else {
329  value[value_idx] = token_str.Atof() ;
330  value_idx++ ;
331  }
332  }
333  token = R__STRTOK_R(NULL, option, &rest); // next token
334  token_idx++ ;
335  }
336  if (!isLineToBeSkipped && value_idx > 1) { //i.e. 2,3 or 4
337  x = value[0] ;
338  y = value[1] ;
339  ex = value[2] ;
340  ey = value[3] ;
341  SetPoint(np, x, y) ;
342  SetPointError(np, ex, ey);
343  np++ ;
344  }
345  }
346  isLineToBeSkipped = kFALSE ;
347  token = NULL ;
348  token_idx = 0 ;
349  value_idx = 0 ;
350  }
351  Set(np) ;
352 
353  // Cleaning
354  delete [] isTokenToBeSaved ;
355  delete [] value ;
356  delete token ;
357  }
358  infile.close();
359 }
360 
361 
362 ////////////////////////////////////////////////////////////////////////////////
363 /// TGraphErrors default destructor.
364 
366 {
367  delete [] fEX;
368  delete [] fEY;
369 }
370 
371 
372 ////////////////////////////////////////////////////////////////////////////////
373 /// apply function to all the data points
374 /// y = f(x,y)
375 ///
376 /// The error is calculated as ey=(f(x,y+ey)-f(x,y-ey))/2
377 /// This is the same as error(fy) = df/dy * ey for small errors
378 ///
379 /// For generic functions the symmetric errors might become non-symmetric
380 /// and are averaged here. Use TGraphAsymmErrors if desired.
381 ///
382 /// error on x doesn't change
383 /// function suggested/implemented by Miroslav Helbich <helbich@mail.desy.de>
384 
386 {
387  Double_t x, y, ex, ey;
388 
389  if (fHistogram) {
390  delete fHistogram;
391  fHistogram = 0;
392  }
393  for (Int_t i = 0; i < GetN(); i++) {
394  GetPoint(i, x, y);
395  ex = GetErrorX(i);
396  ey = GetErrorY(i);
397 
398  SetPoint(i, x, f->Eval(x, y));
399  SetPointError(i, ex, TMath::Abs(f->Eval(x, y + ey) - f->Eval(x, y - ey)) / 2.);
400  }
401  if (gPad) gPad->Modified();
402 }
403 
404 ////////////////////////////////////////////////////////////////////////////////
405 /// apply function to all the data points
406 /// x = f(x,y)
407 ///
408 /// The error is calculated as ex=(f(x+ex,y)-f(x-ex,y))/2
409 /// This is the same as error(fx) = df/dx * ex for small errors
410 ///
411 /// For generic functions the symmetric errors might become non-symmetric
412 /// and are averaged here. Use TGraphAsymmErrors if desired.
413 ///
414 /// error on y doesn't change
415 
417 {
418  Double_t x, y, ex, ey;
419 
420  if (fHistogram) {
421  delete fHistogram;
422  fHistogram = 0;
423  }
424  for (Int_t i = 0; i < GetN(); i++) {
425  GetPoint(i, x, y);
426  ex = GetErrorX(i);
427  ey = GetErrorY(i);
428 
429  SetPoint(i, f->Eval(x,y), y);
430  SetPointError(i, TMath::Abs(f->Eval(x + ex, y) - f->Eval(x - ex, y)) / 2. , ey);
431  }
432  if (gPad) gPad->Modified();
433 }
434 
435 
436 ////////////////////////////////////////////////////////////////////////////////
437 /// Calculate scan fields.
438 
440 {
441  Int_t fields = 0;
442  while ((fmt = strchr(fmt, '%'))) {
443  Bool_t skip = kFALSE;
444  while (*(++fmt)) {
445  if ('[' == *fmt) {
446  if (*++fmt && '^' == *fmt) ++fmt; // "%[^]a]"
447  if (*++fmt && ']' == *fmt) ++fmt; // "%[]a]" or "%[^]a]"
448  while (*fmt && *fmt != ']')
449  ++fmt;
450  if (!skip) ++fields;
451  break;
452  }
453  if ('%' == *fmt) break; // %% literal %
454  if ('*' == *fmt) {
455  skip = kTRUE; // %*d -- skip a number
456  } else if (strchr("dDiouxXxfegEscpn", *fmt)) {
457  if (!skip) ++fields;
458  break;
459  }
460  // skip modifiers & field width
461  }
462  }
463  return fields;
464 }
465 
466 
467 ////////////////////////////////////////////////////////////////////////////////
468 /// Compute range.
469 
471 {
473 
474  for (Int_t i = 0; i < fNpoints; i++) {
475  if (fX[i] - fEX[i] < xmin) {
476  if (gPad && gPad->GetLogx()) {
477  if (fEX[i] < fX[i]) xmin = fX[i] - fEX[i];
478  else xmin = TMath::Min(xmin, fX[i] / 3);
479  } else {
480  xmin = fX[i] - fEX[i];
481  }
482  }
483  if (fX[i] + fEX[i] > xmax) xmax = fX[i] + fEX[i];
484  if (fY[i] - fEY[i] < ymin) {
485  if (gPad && gPad->GetLogy()) {
486  if (fEY[i] < fY[i]) ymin = fY[i] - fEY[i];
487  else ymin = TMath::Min(ymin, fY[i] / 3);
488  } else {
489  ymin = fY[i] - fEY[i];
490  }
491  }
492  if (fY[i] + fEY[i] > ymax) ymax = fY[i] + fEY[i];
493  }
494 }
495 
496 
497 ////////////////////////////////////////////////////////////////////////////////
498 /// Copy and release.
499 
501  Int_t ibegin, Int_t iend, Int_t obegin)
502 {
503  CopyPoints(newarrays, ibegin, iend, obegin);
504  if (newarrays) {
505  delete[] fX;
506  fX = newarrays[2];
507  delete[] fY;
508  fY = newarrays[3];
509  delete[] fEX;
510  fEX = newarrays[0];
511  delete[] fEY;
512  fEY = newarrays[1];
513  delete[] newarrays;
514  }
515 }
516 
517 
518 ////////////////////////////////////////////////////////////////////////////////
519 /// Copy errors from fEX and fEY to arrays[0] and arrays[1]
520 /// or to fX and fY. Copy points.
521 
523  Int_t obegin)
524 {
525  if (TGraph::CopyPoints(arrays ? arrays + 2 : 0, ibegin, iend, obegin)) {
526  Int_t n = (iend - ibegin) * sizeof(Double_t);
527  if (arrays) {
528  memmove(&arrays[0][obegin], &fEX[ibegin], n);
529  memmove(&arrays[1][obegin], &fEY[ibegin], n);
530  } else {
531  memmove(&fEX[obegin], &fEX[ibegin], n);
532  memmove(&fEY[obegin], &fEY[ibegin], n);
533  }
534  return kTRUE;
535  } else {
536  return kFALSE;
537  }
538 }
539 
540 
541 ////////////////////////////////////////////////////////////////////////////////
542 /// Constructor allocate.
543 ///Note: This function should be called only from the constructor
544 /// since it does not delete previously existing arrays
545 
547 {
548 
549  if (!fNpoints) {
550  fEX = fEY = 0;
551  return kFALSE;
552  } else {
553  fEX = new Double_t[fMaxSize];
554  fEY = new Double_t[fMaxSize];
555  }
556  return kTRUE;
557 }
558 
559 ////////////////////////////////////////////////////////////////////////////////
560 /// protected function to perform the merge operation of a graph with errors
561 
563 {
564  if (g->GetN() == 0) return kFALSE;
565 
566  Double_t * ex = g->GetEX();
567  Double_t * ey = g->GetEY();
568  if (ex == 0 || ey == 0 ) {
569  if (g->IsA() != TGraph::Class() )
570  Warning("DoMerge","Merging a %s is not compatible with a TGraphErrors - errors will be ignored",g->IsA()->GetName());
571  return TGraph::DoMerge(g);
572  }
573  for (Int_t i = 0 ; i < g->GetN(); i++) {
574  Int_t ipoint = GetN();
575  Double_t x = g->GetX()[i];
576  Double_t y = g->GetY()[i];
577  SetPoint(ipoint, x, y);
578  SetPointError( ipoint, ex[i], ey[i] );
579  }
580  return kTRUE;
581 }
582 
583 
584 ////////////////////////////////////////////////////////////////////////////////
585 /// Set zero values for point arrays in the range [begin, end]
586 
587 void TGraphErrors::FillZero(Int_t begin, Int_t end, Bool_t from_ctor)
588 {
589  if (!from_ctor) {
590  TGraph::FillZero(begin, end, from_ctor);
591  }
592  Int_t n = (end - begin) * sizeof(Double_t);
593  memset(fEX + begin, 0, n);
594  memset(fEY + begin, 0, n);
595 }
596 
597 
598 ////////////////////////////////////////////////////////////////////////////////
599 /// This function is called by GraphFitChisquare.
600 /// It returns the error along X at point i.
601 
603 {
604  if (i < 0 || i >= fNpoints) return -1;
605  if (fEX) return fEX[i];
606  return -1;
607 }
608 
609 
610 ////////////////////////////////////////////////////////////////////////////////
611 /// This function is called by GraphFitChisquare.
612 /// It returns the error along Y at point i.
613 
615 {
616  if (i < 0 || i >= fNpoints) return -1;
617  if (fEY) return fEY[i];
618  return -1;
619 }
620 
621 
622 ////////////////////////////////////////////////////////////////////////////////
623 /// This function is called by GraphFitChisquare.
624 /// It returns the error along X at point i.
625 
627 {
628  if (i < 0 || i >= fNpoints) return -1;
629  if (fEX) return fEX[i];
630  return -1;
631 }
632 
633 
634 ////////////////////////////////////////////////////////////////////////////////
635 /// This function is called by GraphFitChisquare.
636 /// It returns the error along X at point i.
637 
639 {
640  if (i < 0 || i >= fNpoints) return -1;
641  if (fEX) return fEX[i];
642  return -1;
643 }
644 
645 
646 ////////////////////////////////////////////////////////////////////////////////
647 /// This function is called by GraphFitChisquare.
648 /// It returns the error along X at point i.
649 
651 {
652  if (i < 0 || i >= fNpoints) return -1;
653  if (fEY) return fEY[i];
654  return -1;
655 }
656 
657 
658 ////////////////////////////////////////////////////////////////////////////////
659 /// This function is called by GraphFitChisquare.
660 /// It returns the error along X at point i.
661 
663 {
664  if (i < 0 || i >= fNpoints) return -1;
665  if (fEY) return fEY[i];
666  return -1;
667 }
668 
669 ////////////////////////////////////////////////////////////////////////////////
670 /// Adds all graphs with errors from the collection to this graph.
671 /// Returns the total number of poins in the result or -1 in case of an error.
672 
674 {
675  TIter next(li);
676  while (TObject* o = next()) {
677  TGraph *g = dynamic_cast<TGraph*>(o);
678  if (!g) {
679  Error("Merge",
680  "Cannot merge - an object which doesn't inherit from TGraph found in the list");
681  return -1;
682  }
683  int n0 = GetN();
684  int n1 = n0+g->GetN();
685  Set(n1);
686  Double_t * x = g->GetX();
687  Double_t * y = g->GetY();
688  Double_t * ex = g->GetEX();
689  Double_t * ey = g->GetEY();
690  for (Int_t i = 0 ; i < g->GetN(); i++) {
691  SetPoint(n0+i, x[i], y[i]);
692  if (ex) fEX[n0+i] = ex[i];
693  if (ey) fEY[n0+i] = ey[i];
694  }
695  }
696  return GetN();
697 }
698 
699 ////////////////////////////////////////////////////////////////////////////////
700 /// Print graph and errors values.
701 
703 {
704  for (Int_t i = 0; i < fNpoints; i++) {
705  printf("x[%d]=%g, y[%d]=%g, ex[%d]=%g, ey[%d]=%g\n", i, fX[i], i, fY[i], i, fEX[i], i, fEY[i]);
706  }
707 }
708 
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// Save primitive as a C++ statement(s) on output stream out
712 
713 void TGraphErrors::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
714 {
715  char quote = '"';
716  out << " " << std::endl;
717  static Int_t frameNumber = 1000;
718  frameNumber++;
719 
720  Int_t i;
721  TString fXName = TString(GetName()) + Form("_fx%d",frameNumber);
722  TString fYName = TString(GetName()) + Form("_fy%d",frameNumber);
723  TString fEXName = TString(GetName()) + Form("_fex%d",frameNumber);
724  TString fEYName = TString(GetName()) + Form("_fey%d",frameNumber);
725  out << " Double_t " << fXName << "[" << fNpoints << "] = {" << std::endl;
726  for (i = 0; i < fNpoints-1; i++) out << " " << fX[i] << "," << std::endl;
727  out << " " << fX[fNpoints-1] << "};" << std::endl;
728  out << " Double_t " << fYName << "[" << fNpoints << "] = {" << std::endl;
729  for (i = 0; i < fNpoints-1; i++) out << " " << fY[i] << "," << std::endl;
730  out << " " << fY[fNpoints-1] << "};" << std::endl;
731  out << " Double_t " << fEXName << "[" << fNpoints << "] = {" << std::endl;
732  for (i = 0; i < fNpoints-1; i++) out << " " << fEX[i] << "," << std::endl;
733  out << " " << fEX[fNpoints-1] << "};" << std::endl;
734  out << " Double_t " << fEYName << "[" << fNpoints << "] = {" << std::endl;
735  for (i = 0; i < fNpoints-1; i++) out << " " << fEY[i] << "," << std::endl;
736  out << " " << fEY[fNpoints-1] << "};" << std::endl;
737 
738  if (gROOT->ClassSaved(TGraphErrors::Class())) out << " ";
739  else out << " TGraphErrors *";
740  out << "gre = new TGraphErrors(" << fNpoints << ","
741  << fXName << "," << fYName << ","
742  << fEXName << "," << fEYName << ");"
743  << std::endl;
744 
745  out << " gre->SetName(" << quote << GetName() << quote << ");" << std::endl;
746  out << " gre->SetTitle(" << quote << GetTitle() << quote << ");" << std::endl;
747 
748  SaveFillAttributes(out, "gre", 0, 1001);
749  SaveLineAttributes(out, "gre", 1, 1, 1);
750  SaveMarkerAttributes(out, "gre", 1, 1, 1);
751 
752  if (fHistogram) {
753  TString hname = fHistogram->GetName();
754  hname += frameNumber;
755  fHistogram->SetName(Form("Graph_%s", hname.Data()));
756  fHistogram->SavePrimitive(out, "nodraw");
757  out << " gre->SetHistogram(" << fHistogram->GetName() << ");" << std::endl;
758  out << " " << std::endl;
759  }
760 
761  // save list of functions
762  TIter next(fFunctions);
763  TObject *obj;
764  while ((obj = next())) {
765  obj->SavePrimitive(out, Form("nodraw #%d\n",++frameNumber));
766  if (obj->InheritsFrom("TPaveStats")) {
767  out << " gre->GetListOfFunctions()->Add(ptstats);" << std::endl;
768  out << " ptstats->SetParent(gre->GetListOfFunctions());" << std::endl;
769  } else {
770  TString objname;
771  objname.Form("%s%d",obj->GetName(),frameNumber);
772  if (obj->InheritsFrom("TF1")) {
773  out << " " << objname << "->SetParent(gre);\n";
774  }
775  out << " gre->GetListOfFunctions()->Add("
776  << objname << ");" << std::endl;
777  }
778  }
779 
780  const char *l = strstr(option, "multigraph");
781  if (l) {
782  out << " multigraph->Add(gre," << quote << l + 10 << quote << ");" << std::endl;
783  } else {
784  out << " gre->Draw(" << quote << option << quote << ");" << std::endl;
785  }
786 }
787 
788 
789 ////////////////////////////////////////////////////////////////////////////////
790 /// Set ex and ey values for point pointed by the mouse.
791 
793 {
794  Int_t px = gPad->GetEventX();
795  Int_t py = gPad->GetEventY();
796 
797  //localize point to be deleted
798  Int_t ipoint = -2;
799  Int_t i;
800  // start with a small window (in case the mouse is very close to one point)
801  for (i = 0; i < fNpoints; i++) {
802  Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
803  Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
804  if (dpx * dpx + dpy * dpy < 25) {
805  ipoint = i;
806  break;
807  }
808  }
809  if (ipoint == -2) return;
810 
811  fEX[ipoint] = ex;
812  fEY[ipoint] = ey;
813  gPad->Modified();
814 }
815 
816 
817 ////////////////////////////////////////////////////////////////////////////////
818 /// Set ex and ey values for point number i.
819 
821 {
822  if (i < 0) return;
823  if (i >= fNpoints) {
824  // re-allocate the object
825  TGraphErrors::SetPoint(i, 0, 0);
826  }
827  fEX[i] = ex;
828  fEY[i] = ey;
829 }
830 
831 
832 ////////////////////////////////////////////////////////////////////////////////
833 /// Stream an object of class TGraphErrors.
834 
835 void TGraphErrors::Streamer(TBuffer &b)
836 {
837  if (b.IsReading()) {
838  UInt_t R__s, R__c;
839  Version_t R__v = b.ReadVersion(&R__s, &R__c);
840  if (R__v > 2) {
841  b.ReadClassBuffer(TGraphErrors::Class(), this, R__v, R__s, R__c);
842  return;
843  }
844  //====process old versions before automatic schema evolution
845  TGraph::Streamer(b);
846  fEX = new Double_t[fNpoints];
847  fEY = new Double_t[fNpoints];
848  if (R__v < 2) {
849  Float_t *ex = new Float_t[fNpoints];
850  Float_t *ey = new Float_t[fNpoints];
851  b.ReadFastArray(ex, fNpoints);
852  b.ReadFastArray(ey, fNpoints);
853  for (Int_t i = 0; i < fNpoints; i++) {
854  fEX[i] = ex[i];
855  fEY[i] = ey[i];
856  }
857  delete [] ey;
858  delete [] ex;
859  } else {
860  b.ReadFastArray(fEX, fNpoints);
861  b.ReadFastArray(fEY, fNpoints);
862  }
863  b.CheckByteCount(R__s, R__c, TGraphErrors::IsA());
864  //====end of old versions
865 
866  } else {
867  b.WriteClassBuffer(TGraphErrors::Class(), this);
868  }
869 }
870 
871 
872 ////////////////////////////////////////////////////////////////////////////////
873 /// Swap points
874 
876 {
877  SwapValues(fEX, pos1, pos2);
878  SwapValues(fEY, pos1, pos2);
879  TGraph::SwapPoints(pos1, pos2);
880 }
l
auto * l
Definition: textangle.C:4
ex
Double_t ex[n]
Definition: legend1.C:17
n
const Int_t n
Definition: legend1.C:16
TObject::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TObject.cxx:666
ymax
float ymax
Definition: THbookFile.cxx:95
TGraphErrors::Apply
virtual void Apply(TF1 *f)
apply function to all the data points y = f(x,y)
Definition: TGraphErrors.cxx:385
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TGraph::fFunctions
TList * fFunctions
Pointer to list of functions (fits and user)
Definition: TGraph.h:49
TVectorD.h
Version_t
short Version_t
Definition: RtypesCore.h:65
TGraphErrors::CopyPoints
virtual Bool_t CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend, Int_t obegin)
Copy errors from fEX and fEY to arrays[0] and arrays[1] or to fX and fY.
Definition: TGraphErrors.cxx:522
TH1::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TH1.cxx:7008
f
#define f(i)
Definition: RSha256.hxx:104
TGraph::fHistogram
TH1F * fHistogram
Pointer to histogram used for drawing axis.
Definition: TGraph.h:50
Option_t
const char Option_t
Definition: RtypesCore.h:66
TString::Atoi
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1921
TGraph::fMaxSize
Int_t fMaxSize
!Current dimension of arrays fX and fY
Definition: TGraph.h:45
TGraphErrors::fEX
Double_t * fEX
[fNpoints] array of X errors
Definition: TGraphErrors.h:29
TGraph::CopyPoints
virtual Bool_t CopyPoints(Double_t **newarrays, Int_t ibegin, Int_t iend, Int_t obegin)
Copy points from fX and fY to arrays[0] and arrays[1] or to fX and fY if arrays == 0 and ibegin !...
Definition: TGraph.cxx:708
TGraphErrors::GetErrorY
Double_t GetErrorY(Int_t bin) const
This function is called by GraphFitChisquare.
Definition: TGraphErrors.cxx:614
TString::Data
const char * Data() const
Definition: TString.h:369
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
Form
char * Form(const char *fmt,...)
TNamed::GetTitle
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
xmax
float xmax
Definition: THbookFile.cxx:95
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:890
TString::Atof
Double_t Atof() const
Return floating-point value contained in string.
Definition: TString.cxx:1987
TGraph::operator=
TGraph & operator=(const TGraph &)
Equal operator for this graph.
Definition: TGraph.cxx:188
Float_t
float Float_t
Definition: RtypesCore.h:57
TStyle.h
TGraphErrors::FillZero
virtual void FillZero(Int_t begin, Int_t end, Bool_t from_ctor=kTRUE)
Set zero values for point arrays in the range [begin, end].
Definition: TGraphErrors.cxx:587
Int_t
int Int_t
Definition: RtypesCore.h:45
TGraph::fX
Double_t * fX
[fNpoints] array of X points
Definition: TGraph.h:47
TAttLine::SaveLineAttributes
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition: TAttLine.cxx:270
x
Double_t x[n]
Definition: legend1.C:17
TString::Length
Ssiz_t Length() const
Definition: TString.h:410
TMath::Abs
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
TBuffer
Buffer base class used for serializing objects.
Definition: TBuffer.h:43
TString::IsFloat
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition: TString.cxx:1791
TString::Format
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
TH1::SetName
virtual void SetName(const char *name)
Change the name of this histogram.
Definition: TH1.cxx:8635
TGraphErrors::~TGraphErrors
virtual ~TGraphErrors()
TGraphErrors default destructor.
Definition: TGraphErrors.cxx:365
TString
Basic string class.
Definition: TString.h:136
TAttFill::SaveFillAttributes
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition: TAttFill.cxx:234
TObject::InheritsFrom
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
TGraphErrors::GetErrorYhigh
Double_t GetErrorYhigh(Int_t bin) const
This function is called by GraphFitChisquare.
Definition: TGraphErrors.cxx:650
b
#define b(i)
Definition: RSha256.hxx:100
TGraphErrors::ComputeRange
virtual void ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const
Compute range.
Definition: TGraphErrors.cxx:470
bool
TString::ReplaceAll
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:692
TGraphErrors::fEY
Double_t * fEY
[fNpoints] array of Y errors
Definition: TGraphErrors.h:30
TGraph::SwapPoints
virtual void SwapPoints(Int_t pos1, Int_t pos2)
Swap points.
Definition: TGraph.cxx:2491
TROOT.h
TGraphErrors::Print
virtual void Print(Option_t *chopt="") const
Print graph and errors values.
Definition: TGraphErrors.cxx:702
TObject::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
TGraphErrors::TGraphErrors
TGraphErrors()
TGraphErrors default constructor.
Definition: TGraphErrors.cxx:69
TGraph::DoMerge
virtual Bool_t DoMerge(const TGraph *g)
protected function to perform the merge operation of a graph
Definition: TGraph.cxx:2565
TGraphErrors::GetErrorXhigh
Double_t GetErrorXhigh(Int_t bin) const
This function is called by GraphFitChisquare.
Definition: TGraphErrors.cxx:626
TString::Form
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
TAttMarker::SaveMarkerAttributes
virtual void SaveMarkerAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t sizdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition: TAttMarker.cxx:339
TBuffer.h
gStyle
R__EXTERN TStyle * gStyle
Definition: TStyle.h:412
TSystem.h
xmin
float xmin
Definition: THbookFile.cxx:95
h
#define h(i)
Definition: RSha256.hxx:106
gr
TGraphErrors * gr
Definition: legend1.C:25
TGraphErrors::SavePrimitive
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TGraphErrors.cxx:713
TGraphErrors::GetErrorXlow
Double_t GetErrorXlow(Int_t bin) const
This function is called by GraphFitChisquare.
Definition: TGraphErrors.cxx:638
TGraphErrors::DoMerge
virtual Bool_t DoMerge(const TGraph *g)
protected function to perform the merge operation of a graph with errors
Definition: TGraphErrors.cxx:562
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TVirtualPad.h
UInt_t
unsigned int UInt_t
Definition: RtypesCore.h:46
TGraph::FillZero
virtual void FillZero(Int_t begin, Int_t end, Bool_t from_ctor=kTRUE)
Set zero values for point arrays in the range [begin, end) Should be redefined in descendant classes.
Definition: TGraph.cxx:1028
TGraph::fY
Double_t * fY
[fNpoints] array of Y points
Definition: TGraph.h:48
y
Double_t y[n]
Definition: legend1.C:17
ey
Double_t ey[n]
Definition: legend1.C:17
TObject::MakeZombie
void MakeZombie()
Definition: TObject.h:49
TSystem::ExpandPathName
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1272
TGraphErrors::CtorAllocate
Bool_t CtorAllocate()
Constructor allocate.
Definition: TGraphErrors.cxx:546
TGraphErrors::GetErrorYlow
Double_t GetErrorYlow(Int_t bin) const
This function is called by GraphFitChisquare.
Definition: TGraphErrors.cxx:662
line
TLine * line
Definition: entrylistblock_figure1.C:235
TObject::Warning
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:876
TString::IsDigit
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1763
TGraph::SetPoint
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition: TGraph.cxx:2269
TMath::Min
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
TGraphErrors::CalculateScanfFields
static Int_t CalculateScanfFields(const char *fmt)
Calculate scan fields.
Definition: TGraphErrors.cxx:439
TGraph::GetPoint
virtual Int_t GetPoint(Int_t i, Double_t &x, Double_t &y) const
Get x and y values for point number i.
Definition: TGraph.cxx:1593
ymin
float ymin
Definition: THbookFile.cxx:95
gSystem
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
TStyle::GetErrorX
Float_t GetErrorX() const
Definition: TStyle.h:178
TGraph::ComputeRange
virtual void ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const
Compute the x/y range of the points in this graph.
Definition: TGraph.cxx:660
TGraphErrors::SetPointError
virtual void SetPointError(Double_t ex, Double_t ey)
Set ex and ey values for point pointed by the mouse.
Definition: TGraphErrors.cxx:792
TGraph::Set
virtual void Set(Int_t n)
Set number of points in the graph Existing coordinates are preserved New coordinates above fNpoints a...
Definition: TGraph.cxx:2204
TGraphErrors::operator=
TGraphErrors & operator=(const TGraphErrors &gr)
TGraphErrors assignment operator.
Definition: TGraphErrors.cxx:182
TVectorT
TVectorT.
Definition: TVectorT.h:27
TGraph::SwapValues
static void SwapValues(Double_t *arr, Int_t pos1, Int_t pos2)
Swap values.
Definition: TGraph.cxx:2500
Double_t
double Double_t
Definition: RtypesCore.h:59
TGraph
A TGraph is an object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
TGraphErrors
A TGraphErrors is a TGraph with error bars.
Definition: TGraphErrors.h:26
TF1.h
TGraphErrors::Merge
virtual Int_t Merge(TCollection *list)
Adds all graphs with errors from the collection to this graph.
Definition: TGraphErrors.cxx:673
TObject
Mother of all ROOT objects.
Definition: TObject.h:37
TGraphErrors::SwapPoints
virtual void SwapPoints(Int_t pos1, Int_t pos2)
Swap points.
Definition: TGraphErrors.cxx:875
TH1
TH1 is the base class of all histogramm classes in ROOT.
Definition: TH1.h:58
TGraph::GetN
Int_t GetN() const
Definition: TGraph.h:123
TGraphErrors::CopyAndRelease
virtual void CopyAndRelease(Double_t **newarrays, Int_t ibegin, Int_t iend, Int_t obegin)
Copy and release.
Definition: TGraphErrors.cxx:500
gPad
#define gPad
Definition: TVirtualPad.h:287
TGraphErrors::ApplyX
virtual void ApplyX(TF1 *f)
apply function to all the data points x = f(x,y)
Definition: TGraphErrors.cxx:416
TIter
Definition: TCollection.h:233
TGraph::fNpoints
Int_t fNpoints
Number of points <= fMaxSize.
Definition: TGraph.h:46
TCollection
Collection abstract base class.
Definition: TCollection.h:63
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
TGraphErrors::GetErrorX
Double_t GetErrorX(Int_t bin) const
This function is called by GraphFitChisquare.
Definition: TGraphErrors.cxx:602
TGraphErrors.h
TF1
1-Dim function class
Definition: TF1.h:213
Class
void Class()
Definition: Class.C:29
TH1.h
TVectorT::GetLwb
Int_t GetLwb() const
Definition: TVectorT.h:73
TMath
TMath.
Definition: TMathBase.h:35
TMath.h
gROOT
#define gROOT
Definition: TROOT.h:406
int
g
#define g(i)
Definition: RSha256.hxx:105