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
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
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);
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 = nullptr;
310 TString token_str = "";
311 Int_t token_idx = 0;
312 Double_t value[4]; //x,y,ex,ey buffers
313 for (Int_t k = 0; k < 4; k++)
314 value[k] = 0.;
315 Int_t value_idx = 0;
316
317 // Looping
318 char *rest;
319 while (std::getline(infile, line, '\n')) {
320 if (!line.empty()) {
321 if (line[line.size() - 1] == char(13)) { // removing DOS CR character
322 line.erase(line.end() - 1, line.end()) ;
323 }
324 token = R__STRTOK_R(const_cast<char *>(line.c_str()), option, &rest);
325 while (token != nullptr && value_idx < ntokensToBeSaved) {
326 if (isTokenToBeSaved[token_idx]) {
327 token_str = TString(token) ;
328 token_str.ReplaceAll("\t", "") ;
329 if (!token_str.IsFloat()) {
330 isLineToBeSkipped = kTRUE ;
331 break ;
332 } else {
333 value[value_idx] = token_str.Atof() ;
334 value_idx++ ;
335 }
336 }
337 token = R__STRTOK_R(nullptr, option, &rest); // next token
338 token_idx++ ;
339 }
340 if (!isLineToBeSkipped && value_idx > 1) { //i.e. 2,3 or 4
341 x = value[0];
342 y = value[1];
343 ex = value[2];
344 ey = value[3];
345 SetPoint(np, x, y);
347 np++ ;
348 }
349 }
350 isLineToBeSkipped = kFALSE;
351 token = nullptr;
352 token_idx = 0;
353 value_idx = 0;
354 }
355 Set(np) ;
356
357 // Cleaning
358 delete [] isTokenToBeSaved;
359 delete token;
360 }
361 infile.close();
362}
363
364
365////////////////////////////////////////////////////////////////////////////////
366/// TGraphErrors default destructor.
367
369{
370 delete [] fEX;
371 delete [] fEY;
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Add a point with errorbars to the graph.
376
378{
379 AddPoint(x, y); // fNpoints will increase automatically
381}
382
383////////////////////////////////////////////////////////////////////////////////
384/// Apply function to all the data points \f$ y = f(x,y) \f$.
385///
386/// The error is calculated as \f$ ey=(f(x,y+ey)-f(x,y-ey))/2 \f$.
387/// This is the same as \f$ error(fy) = df/dy * ey \f$ for small errors.
388///
389/// For generic functions the symmetric errors might become non-symmetric
390/// and are averaged here. Use TGraphAsymmErrors if desired.
391///
392/// Error on \f$ x \f$ doesn't change.
393///
394/// function suggested/implemented by Miroslav Helbich <helbich@mail.desy.de>
395
397{
398 Double_t x, y, ex, ey;
399
400 if (fHistogram) {
401 delete fHistogram;
402 fHistogram = nullptr;
403 }
404 for (Int_t i = 0; i < GetN(); i++) {
405 GetPoint(i, x, y);
406 ex = GetErrorX(i);
407 ey = GetErrorY(i);
408
409 SetPoint(i, x, f->Eval(x, y));
410 SetPointError(i, ex, TMath::Abs(f->Eval(x, y + ey) - f->Eval(x, y - ey)) / 2.);
411 }
412 if (gPad) gPad->Modified();
413}
414
415////////////////////////////////////////////////////////////////////////////////
416/// Apply function to all the data points \f$ x = f(x,y) \f$.
417///
418/// The error is calculated as \f$ ex=(f(x+ex,y)-f(x-ex,y))/2 \f$.
419/// This is the same as \f$ error(fx) = df/dx * ex \f$ for small errors.
420///
421/// For generic functions the symmetric errors might become non-symmetric
422/// and are averaged here. Use TGraphAsymmErrors if desired.
423///
424/// Error on \f$ y \f$ doesn't change.
425
427{
428 Double_t x, y, ex, ey;
429
430 if (fHistogram) {
431 delete fHistogram;
432 fHistogram = nullptr;
433 }
434 for (Int_t i = 0; i < GetN(); i++) {
435 GetPoint(i, x, y);
436 ex = GetErrorX(i);
437 ey = GetErrorY(i);
438
439 SetPoint(i, f->Eval(x,y), y);
440 SetPointError(i, TMath::Abs(f->Eval(x + ex, y) - f->Eval(x - ex, y)) / 2. , ey);
441 }
442 if (gPad) gPad->Modified();
443}
444
445
446////////////////////////////////////////////////////////////////////////////////
447/// Calculate scan fields.
448
450{
451 Int_t fields = 0;
452 while ((fmt = strchr(fmt, '%'))) {
453 Bool_t skip = kFALSE;
454 while (*(++fmt)) {
455 if ('[' == *fmt) {
456 if (*++fmt && '^' == *fmt) ++fmt; // "%[^]a]"
457 if (*++fmt && ']' == *fmt) ++fmt; // "%[]a]" or "%[^]a]"
458 while (*fmt && *fmt != ']')
459 ++fmt;
460 if (!skip) ++fields;
461 break;
462 }
463 if ('%' == *fmt) break; // %% literal %
464 if ('*' == *fmt) {
465 skip = kTRUE; // %*d -- skip a number
466 } else if (strchr("dDiouxXxfegEscpn", *fmt)) {
467 if (!skip) ++fields;
468 break;
469 }
470 // skip modifiers & field width
471 }
472 }
473 return fields;
474}
475
476
477////////////////////////////////////////////////////////////////////////////////
478/// Compute range.
479
481{
483
484 for (Int_t i = 0; i < fNpoints; i++) {
485 if (fX[i] - fEX[i] < xmin) {
486 if (gPad && gPad->GetLogx()) {
487 if (fEX[i] < fX[i]) xmin = fX[i] - fEX[i];
488 else xmin = TMath::Min(xmin, fX[i] / 3);
489 } else {
490 xmin = fX[i] - fEX[i];
491 }
492 }
493 if (fX[i] + fEX[i] > xmax) xmax = fX[i] + fEX[i];
494 if (fY[i] - fEY[i] < ymin) {
495 if (gPad && gPad->GetLogy()) {
496 if (fEY[i] < fY[i]) ymin = fY[i] - fEY[i];
497 else ymin = TMath::Min(ymin, fY[i] / 3);
498 } else {
499 ymin = fY[i] - fEY[i];
500 }
501 }
502 if (fY[i] + fEY[i] > ymax) ymax = fY[i] + fEY[i];
503 }
504}
505
506
507////////////////////////////////////////////////////////////////////////////////
508/// Copy and release.
509
511 Int_t ibegin, Int_t iend, Int_t obegin)
512{
513 CopyPoints(newarrays, ibegin, iend, obegin);
514 if (newarrays) {
515 delete[] fX;
516 fX = newarrays[2];
517 delete[] fY;
518 fY = newarrays[3];
519 delete[] fEX;
520 fEX = newarrays[0];
521 delete[] fEY;
522 fEY = newarrays[1];
523 delete[] newarrays;
524 }
525}
526
527
528////////////////////////////////////////////////////////////////////////////////
529/// Copy errors from `fEX` and `fEY` to `arrays[0]` and `arrays[1]`
530/// or to `fEX` and `fEY` if `arrays == 0` and `ibegin != iend`.
531
533 Int_t obegin)
534{
535 if (TGraph::CopyPoints(arrays ? arrays + 2 : nullptr, ibegin, iend, obegin)) {
536 Int_t n = (iend - ibegin) * sizeof(Double_t);
537 if (arrays) {
538 memmove(&arrays[0][obegin], &fEX[ibegin], n);
539 memmove(&arrays[1][obegin], &fEY[ibegin], n);
540 } else {
541 memmove(&fEX[obegin], &fEX[ibegin], n);
542 memmove(&fEY[obegin], &fEY[ibegin], n);
543 }
544 return kTRUE;
545 } else {
546 return kFALSE;
547 }
548}
549
550
551////////////////////////////////////////////////////////////////////////////////
552/// Constructor allocate.
553///
554/// Note: This function should be called only from the constructor
555/// since it does not delete previously existing arrays.
556
558{
559
560 if (!fNpoints) {
561 fEX = fEY = nullptr;
562 return kFALSE;
563 } else {
564 fEX = new Double_t[fMaxSize];
565 fEY = new Double_t[fMaxSize];
566 }
567 return kTRUE;
568}
569
570////////////////////////////////////////////////////////////////////////////////
571/// Protected function to perform the merge operation of a graph with errors.
572
574{
575 if (g->GetN() == 0) return kFALSE;
576
577 Double_t * ex = g->GetEX();
578 Double_t * ey = g->GetEY();
579 if (ex == nullptr || ey == nullptr) {
580 if (g->IsA() != TGraph::Class() )
581 Warning("DoMerge","Merging a %s is not compatible with a TGraphErrors - errors will be ignored",g->IsA()->GetName());
582 return TGraph::DoMerge(g);
583 }
584 for (Int_t i = 0 ; i < g->GetN(); i++) {
585 Int_t ipoint = GetN();
586 Double_t x = g->GetX()[i];
587 Double_t y = g->GetY()[i];
588 SetPoint(ipoint, x, y);
589 SetPointError( ipoint, ex[i], ey[i] );
590 }
591 return kTRUE;
592}
593
594
595////////////////////////////////////////////////////////////////////////////////
596/// Set zero values for point arrays in the range `[begin, end]`.
597
598void TGraphErrors::FillZero(Int_t begin, Int_t end, Bool_t from_ctor)
599{
600 if (!from_ctor) {
601 TGraph::FillZero(begin, end, from_ctor);
602 }
603 Int_t n = (end - begin) * sizeof(Double_t);
604 memset(fEX + begin, 0, n);
605 memset(fEY + begin, 0, n);
606}
607
608
609////////////////////////////////////////////////////////////////////////////////
610/// It returns the error along X at point `i`.
611
613{
614 if (i < 0 || i >= fNpoints) return -1;
615 if (fEX) return fEX[i];
616 return -1;
617}
618
619
620////////////////////////////////////////////////////////////////////////////////
621/// It returns the error along Y at point `i`.
622
624{
625 if (i < 0 || i >= fNpoints) return -1;
626 if (fEY) return fEY[i];
627 return -1;
628}
629
630
631////////////////////////////////////////////////////////////////////////////////
632/// It returns the error along X at point `i`. For TGraphErrors this method is
633/// the same as GetErrorX.
634
636{
637 if (i < 0 || i >= fNpoints) return -1;
638 if (fEX) return fEX[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 Y at point `i`. For TGraphErrors this method is
657/// the same as GetErrorY.
658
660{
661 if (i < 0 || i >= fNpoints) return -1;
662 if (fEY) return fEY[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/// Adds all graphs with errors from the collection to this graph.
680/// Returns the total number of points in the result or -1 in case of an error.
681
683{
684 TIter next(li);
685 while (TObject* o = next()) {
686 TGraph *g = dynamic_cast<TGraph*>(o);
687 if (!g) {
688 Error("Merge",
689 "Cannot merge - an object which doesn't inherit from TGraph found in the list");
690 return -1;
691 }
692 int n0 = GetN();
693 int n1 = n0+g->GetN();
694 Set(n1);
695 Double_t * x = g->GetX();
696 Double_t * y = g->GetY();
697 Double_t * ex = g->GetEX();
698 Double_t * ey = g->GetEY();
699 for (Int_t i = 0 ; i < g->GetN(); i++) {
700 SetPoint(n0+i, x[i], y[i]);
701 if (ex) fEX[n0+i] = ex[i];
702 if (ey) fEY[n0+i] = ey[i];
703 }
704 }
705 return GetN();
706}
707
708////////////////////////////////////////////////////////////////////////////////
709/// Print graph and errors values.
710
712{
713 for (Int_t i = 0; i < fNpoints; i++) {
714 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]);
715 }
716}
717
718
719////////////////////////////////////////////////////////////////////////////////
720/// Save primitive as a C++ statement(s) on output stream out
721
722void TGraphErrors::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
723{
724 out << " " << std::endl;
725 static Int_t frameNumber = 1000;
726 frameNumber++;
727
728 auto fXName = SaveArray(out, "fx", frameNumber, fX);
729 auto fYName = SaveArray(out, "fy", frameNumber, fY);
730 auto fEXName = SaveArray(out, "fex", frameNumber, fEX);
731 auto fEYName = SaveArray(out, "fey", frameNumber, fEY);
732
733 if (gROOT->ClassSaved(TGraphErrors::Class()))
734 out << " ";
735 else
736 out << " TGraphErrors *";
737 out << "gre = new TGraphErrors(" << fNpoints << ","
738 << fXName << "," << fYName << ","
739 << fEXName << "," << fEYName << ");"
740 << std::endl;
741
742 SaveHistogramAndFunctions(out, "gre", frameNumber, option);
743}
744
745////////////////////////////////////////////////////////////////////////////////
746/// Multiply the values and errors of a TGraphErrors by a constant c1.
747///
748/// If option contains "x" the x values and errors are scaled
749/// If option contains "y" the y values and errors are scaled
750/// If option contains "xy" both x and y values and errors are scaled
751
753{
755 TString opt = option; opt.ToLower();
756 if (opt.Contains("x") && GetEX()) {
757 for (Int_t i=0; i<GetN(); i++)
758 GetEX()[i] *= c1;
759 }
760 if (opt.Contains("y") && GetEY()) {
761 for (Int_t i=0; i<GetN(); i++)
762 GetEY()[i] *= c1;
763 }
764}
765
766////////////////////////////////////////////////////////////////////////////////
767/// Set `ex` and `ey` values for point pointed by the mouse.
768
770{
771 if (!gPad) {
772 Error("SetPointError", "Cannot be used without gPad, requires last mouse position");
773 return;
774 }
775
776 Int_t px = gPad->GetEventX();
777 Int_t py = gPad->GetEventY();
778
779 //localize point to be deleted
780 Int_t ipoint = -2;
781 Int_t i;
782 // start with a small window (in case the mouse is very close to one point)
783 for (i = 0; i < fNpoints; i++) {
784 Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
785 Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
786 if (dpx * dpx + dpy * dpy < 25) {
787 ipoint = i;
788 break;
789 }
790 }
791 if (ipoint == -2) return;
792
793 fEX[ipoint] = ex;
794 fEY[ipoint] = ey;
795 gPad->Modified();
796}
797
798
799////////////////////////////////////////////////////////////////////////////////
800/// Set `ex` and `ey` values for point number i.
801
803{
804 if (i < 0) return;
805 if (i >= fNpoints) {
806 // re-allocate the object
807 TGraphErrors::SetPoint(i, 0, 0);
808 }
809 fEX[i] = ex;
810 fEY[i] = ey;
811}
812
813
814////////////////////////////////////////////////////////////////////////////////
815/// Stream an object of class TGraphErrors.
816
818{
819 if (b.IsReading()) {
820 UInt_t R__s, R__c;
821 Version_t R__v = b.ReadVersion(&R__s, &R__c);
822 if (R__v > 2) {
823 b.ReadClassBuffer(TGraphErrors::Class(), this, R__v, R__s, R__c);
824 return;
825 }
826 //====process old versions before automatic schema evolution
828 fEX = new Double_t[fNpoints];
829 fEY = new Double_t[fNpoints];
830 if (R__v < 2) {
831 Float_t *ex = new Float_t[fNpoints];
832 Float_t *ey = new Float_t[fNpoints];
833 b.ReadFastArray(ex, fNpoints);
834 b.ReadFastArray(ey, fNpoints);
835 for (Int_t i = 0; i < fNpoints; i++) {
836 fEX[i] = ex[i];
837 fEY[i] = ey[i];
838 }
839 delete [] ey;
840 delete [] ex;
841 } else {
842 b.ReadFastArray(fEX, fNpoints);
843 b.ReadFastArray(fEY, fNpoints);
844 }
845 b.CheckByteCount(R__s, R__c, TGraphErrors::IsA());
846 //====end of old versions
847
848 } else {
849 b.WriteClassBuffer(TGraphErrors::Class(), this);
850 }
851}
852
853////////////////////////////////////////////////////////////////////////////////
854/// Swap points.
855
857{
858 SwapValues(fEX, pos1, pos2);
859 SwapValues(fEY, pos1, pos2);
860 TGraph::SwapPoints(pos1, pos2);
861}
862
863////////////////////////////////////////////////////////////////////////////////
864/// Update the fX, fY, fEX, and fEY arrays with the sorted values.
865
866void TGraphErrors::UpdateArrays(const std::vector<Int_t> &sorting_indices, Int_t numSortedPoints, Int_t low)
867{
868 std::vector<Double_t> fEXSorted(numSortedPoints);
869 std::vector<Double_t> fEYSorted(numSortedPoints);
870
871 // Fill the sorted X and Y error values based on the sorted indices
872 std::generate(fEXSorted.begin(), fEXSorted.end(),
873 [begin = low, &sorting_indices, this]() mutable { return fEX[sorting_indices[begin++]]; });
874 std::generate(fEYSorted.begin(), fEYSorted.end(),
875 [begin = low, &sorting_indices, this]() mutable { return fEY[sorting_indices[begin++]]; });
876
877 // Copy the sorted X and Y error values back to the original arrays
878 std::copy(fEXSorted.begin(), fEXSorted.end(), fEX + low);
879 std::copy(fEYSorted.begin(), fEYSorted.end(), fEY + low);
880
881 TGraph::UpdateArrays(sorting_indices, numSortedPoints, low);
882}
#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
short Version_t
Definition RtypesCore.h:65
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t format
float xmin
float ymin
float xmax
float ymax
#define gROOT
Definition TROOT.h:407
R__EXTERN TStyle * gStyle
Definition TStyle.h:436
R__EXTERN TSystem * gSystem
Definition TSystem.h:555
#define gPad
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:233
A TGraphErrors is a TGraph with error bars.
void ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const override
Compute range.
void UpdateArrays(const std::vector< Int_t > &sorting_indices, Int_t numSortedPoints, Int_t low) override
Update the fX, fY, fEX, and fEY arrays with the sorted values.
Double_t GetErrorY(Int_t bin) const override
It returns the error along Y at point i.
Double_t * GetEX() const override
Double_t GetErrorX(Int_t bin) const override
It returns the error along X at point i.
Double_t * fEY
[fNpoints] array of Y errors
~TGraphErrors() override
TGraphErrors default destructor.
static TClass * Class()
void Scale(Double_t c1=1., Option_t *option="y") override
Multiply the values and errors of a TGraphErrors by a constant c1.
static Int_t CalculateScanfFields(const char *fmt)
Calculate scan fields.
void Streamer(TBuffer &) override
Stream an object of class TGraphErrors.
void FillZero(Int_t begin, Int_t end, Bool_t from_ctor=kTRUE) override
Set zero values for point arrays in the range [begin, end].
virtual void AddPointError(Double_t x, Double_t y, Double_t ex=0., Double_t ey=0.)
Add a point with errorbars to the graph.
Double_t * fEX
[fNpoints] array of X errors
void Print(Option_t *chopt="") const override
Print graph and errors values.
virtual void SetPointError(Double_t ex, Double_t ey)
Set ex and ey values for point pointed by the mouse.
Bool_t DoMerge(const TGraph *g) override
Protected function to perform the merge operation of a graph with errors.
Double_t * GetEY() const override
void SwapPoints(Int_t pos1, Int_t pos2) override
Swap points.
virtual void ApplyX(TF1 *f)
Apply function to all the data points .
Double_t GetErrorXhigh(Int_t bin) const override
It returns the error along X at point i.
Double_t GetErrorYlow(Int_t bin) const override
It returns the error along Y at point i.
Double_t GetErrorYhigh(Int_t bin) const override
It returns the error along Y at point i.
TGraphErrors & operator=(const TGraphErrors &gr)
TGraphErrors assignment operator.
Bool_t CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend, Int_t obegin) override
Copy errors from fEX and fEY to arrays[0] and arrays[1] or to fEX and fEY if arrays == 0 and ibegin !...
TClass * IsA() const override
Int_t Merge(TCollection *list) override
Adds all graphs with errors from the collection to this graph.
void CopyAndRelease(Double_t **newarrays, Int_t ibegin, Int_t iend, Int_t obegin) override
Copy and release.
TGraphErrors()
TGraphErrors default constructor.
Double_t GetErrorXlow(Int_t bin) const override
It returns the error along X at point i.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
void Apply(TF1 *f) override
Apply function to all the data points .
Bool_t CtorAllocate()
Constructor allocate.
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
static TClass * Class()
virtual void AddPoint(Double_t x, Double_t y)
Append a new point to the graph.
Definition TGraph.h:98
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:2325
Int_t fMaxSize
!Current dimension of arrays fX and fY
Definition TGraph.h:45
void SaveHistogramAndFunctions(std::ostream &out, const char *varname, Int_t &frameNumber, Option_t *option)
Save histogram and list of functions of TGraph as C++ statement Used in all TGraph-derived classes.
Definition TGraph.cxx:2182
TH1F * fHistogram
Pointer to histogram used for drawing axis.
Definition TGraph.h:50
virtual void UpdateArrays(const std::vector< Int_t > &sorting_indices, Int_t numSortedPoints, Int_t low)
Update the fX and fY arrays with the sorted values.
Definition TGraph.cxx:2575
Int_t GetN() const
Definition TGraph.h:131
Double_t * fY
[fNpoints] array of Y points
Definition TGraph.h:48
TString SaveArray(std::ostream &out, const char *suffix, Int_t frameNumber, Double_t *arr)
Save array as C++ code Returns name of created array.
Definition TGraph.cxx:2158
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:714
virtual void Scale(Double_t c1=1., Option_t *option="y")
Multiply the values of a TGraph by a constant c1.
Definition TGraph.cxx:2242
static void SwapValues(Double_t *arr, Int_t pos1, Int_t pos2)
Swap values.
Definition TGraph.cxx:2594
void Streamer(TBuffer &) override
Stream an object of class TGraph.
Definition TGraph.cxx:2499
virtual Bool_t DoMerge(const TGraph *g)
protected function to perform the merge operation of a graph
Definition TGraph.cxx:2659
virtual void SwapPoints(Int_t pos1, Int_t pos2)
Swap points.
Definition TGraph.cxx:2566
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:1085
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:2260
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:1516
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:762
TGraph & operator=(const TGraph &)
Equal operator for this graph.
Definition TGraph.cxx:232
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
void MakeZombie()
Definition TObject.h:53
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1988
Double_t Atof() const
Return floating-point value contained in string.
Definition TString.cxx:2054
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
Definition TString.cxx:1858
const char * Data() const
Definition TString.h:376
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition TString.cxx:1830
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
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:2378
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Float_t GetErrorX() const
Definition TStyle.h:186
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:71
TLine * line
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
Double_t ey[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
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:198
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123