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