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