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