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////////////////////////////////////////////////////////////////////////////////
376/// Apply function to all the data points \f$ y = f(x,y) \f$.
377///
378/// The error is calculated as \f$ ey=(f(x,y+ey)-f(x,y-ey))/2 \f$.
379/// This is the same as \f$ error(fy) = df/dy * ey \f$ for small errors.
380///
381/// For generic functions the symmetric errors might become non-symmetric
382/// and are averaged here. Use TGraphAsymmErrors if desired.
383///
384/// Error on \f$ x \f$ doesn't change.
385///
386/// function suggested/implemented by Miroslav Helbich <helbich@mail.desy.de>
387
389{
390 Double_t x, y, ex, ey;
391
392 if (fHistogram) {
393 delete fHistogram;
394 fHistogram = nullptr;
395 }
396 for (Int_t i = 0; i < GetN(); i++) {
397 GetPoint(i, x, y);
398 ex = GetErrorX(i);
399 ey = GetErrorY(i);
400
401 SetPoint(i, x, f->Eval(x, y));
402 SetPointError(i, ex, TMath::Abs(f->Eval(x, y + ey) - f->Eval(x, y - ey)) / 2.);
403 }
404 if (gPad) gPad->Modified();
405}
406
407////////////////////////////////////////////////////////////////////////////////
408/// Apply function to all the data points \f$ x = f(x,y) \f$.
409///
410/// The error is calculated as \f$ ex=(f(x+ex,y)-f(x-ex,y))/2 \f$.
411/// This is the same as \f$ error(fx) = df/dx * ex \f$ for small errors.
412///
413/// For generic functions the symmetric errors might become non-symmetric
414/// and are averaged here. Use TGraphAsymmErrors if desired.
415///
416/// Error on \f$ y \f$ doesn't change.
417
419{
420 Double_t x, y, ex, ey;
421
422 if (fHistogram) {
423 delete fHistogram;
424 fHistogram = nullptr;
425 }
426 for (Int_t i = 0; i < GetN(); i++) {
427 GetPoint(i, x, y);
428 ex = GetErrorX(i);
429 ey = GetErrorY(i);
430
431 SetPoint(i, f->Eval(x,y), y);
432 SetPointError(i, TMath::Abs(f->Eval(x + ex, y) - f->Eval(x - ex, y)) / 2. , ey);
433 }
434 if (gPad) gPad->Modified();
435}
436
437
438////////////////////////////////////////////////////////////////////////////////
439/// Calculate scan fields.
440
442{
443 Int_t fields = 0;
444 while ((fmt = strchr(fmt, '%'))) {
445 Bool_t skip = kFALSE;
446 while (*(++fmt)) {
447 if ('[' == *fmt) {
448 if (*++fmt && '^' == *fmt) ++fmt; // "%[^]a]"
449 if (*++fmt && ']' == *fmt) ++fmt; // "%[]a]" or "%[^]a]"
450 while (*fmt && *fmt != ']')
451 ++fmt;
452 if (!skip) ++fields;
453 break;
454 }
455 if ('%' == *fmt) break; // %% literal %
456 if ('*' == *fmt) {
457 skip = kTRUE; // %*d -- skip a number
458 } else if (strchr("dDiouxXxfegEscpn", *fmt)) {
459 if (!skip) ++fields;
460 break;
461 }
462 // skip modifiers & field width
463 }
464 }
465 return fields;
466}
467
468
469////////////////////////////////////////////////////////////////////////////////
470/// Compute range.
471
473{
475
476 for (Int_t i = 0; i < fNpoints; i++) {
477 if (fX[i] - fEX[i] < xmin) {
478 if (gPad && gPad->GetLogx()) {
479 if (fEX[i] < fX[i]) xmin = fX[i] - fEX[i];
480 else xmin = TMath::Min(xmin, fX[i] / 3);
481 } else {
482 xmin = fX[i] - fEX[i];
483 }
484 }
485 if (fX[i] + fEX[i] > xmax) xmax = fX[i] + fEX[i];
486 if (fY[i] - fEY[i] < ymin) {
487 if (gPad && gPad->GetLogy()) {
488 if (fEY[i] < fY[i]) ymin = fY[i] - fEY[i];
489 else ymin = TMath::Min(ymin, fY[i] / 3);
490 } else {
491 ymin = fY[i] - fEY[i];
492 }
493 }
494 if (fY[i] + fEY[i] > ymax) ymax = fY[i] + fEY[i];
495 }
496}
497
498
499////////////////////////////////////////////////////////////////////////////////
500/// Copy and release.
501
503 Int_t ibegin, Int_t iend, Int_t obegin)
504{
505 CopyPoints(newarrays, ibegin, iend, obegin);
506 if (newarrays) {
507 delete[] fX;
508 fX = newarrays[2];
509 delete[] fY;
510 fY = newarrays[3];
511 delete[] fEX;
512 fEX = newarrays[0];
513 delete[] fEY;
514 fEY = newarrays[1];
515 delete[] newarrays;
516 }
517}
518
519
520////////////////////////////////////////////////////////////////////////////////
521/// Copy errors from `fEX` and `fEY` to `arrays[0]` and `arrays[1]`
522/// or to `fEX` and `fEY` if `arrays == 0` and `ibegin != iend`.
523
525 Int_t obegin)
526{
527 if (TGraph::CopyPoints(arrays ? arrays + 2 : nullptr, ibegin, iend, obegin)) {
528 Int_t n = (iend - ibegin) * sizeof(Double_t);
529 if (arrays) {
530 memmove(&arrays[0][obegin], &fEX[ibegin], n);
531 memmove(&arrays[1][obegin], &fEY[ibegin], n);
532 } else {
533 memmove(&fEX[obegin], &fEX[ibegin], n);
534 memmove(&fEY[obegin], &fEY[ibegin], n);
535 }
536 return kTRUE;
537 } else {
538 return kFALSE;
539 }
540}
541
542
543////////////////////////////////////////////////////////////////////////////////
544/// Constructor allocate.
545///
546/// Note: This function should be called only from the constructor
547/// since it does not delete previously existing arrays.
548
550{
551
552 if (!fNpoints) {
553 fEX = fEY = nullptr;
554 return kFALSE;
555 } else {
556 fEX = new Double_t[fMaxSize];
557 fEY = new Double_t[fMaxSize];
558 }
559 return kTRUE;
560}
561
562////////////////////////////////////////////////////////////////////////////////
563/// Protected function to perform the merge operation of a graph with errors.
564
566{
567 if (g->GetN() == 0) return kFALSE;
568
569 Double_t * ex = g->GetEX();
570 Double_t * ey = g->GetEY();
571 if (ex == nullptr || ey == nullptr) {
572 if (g->IsA() != TGraph::Class() )
573 Warning("DoMerge","Merging a %s is not compatible with a TGraphErrors - errors will be ignored",g->IsA()->GetName());
574 return TGraph::DoMerge(g);
575 }
576 for (Int_t i = 0 ; i < g->GetN(); i++) {
577 Int_t ipoint = GetN();
578 Double_t x = g->GetX()[i];
579 Double_t y = g->GetY()[i];
580 SetPoint(ipoint, x, y);
581 SetPointError( ipoint, ex[i], ey[i] );
582 }
583 return kTRUE;
584}
585
586
587////////////////////////////////////////////////////////////////////////////////
588/// Set zero values for point arrays in the range `[begin, end]`.
589
590void TGraphErrors::FillZero(Int_t begin, Int_t end, Bool_t from_ctor)
591{
592 if (!from_ctor) {
593 TGraph::FillZero(begin, end, from_ctor);
594 }
595 Int_t n = (end - begin) * sizeof(Double_t);
596 memset(fEX + begin, 0, n);
597 memset(fEY + begin, 0, n);
598}
599
600
601////////////////////////////////////////////////////////////////////////////////
602/// It returns the error along X at point `i`.
603
605{
606 if (i < 0 || i >= fNpoints) return -1;
607 if (fEX) return fEX[i];
608 return -1;
609}
610
611
612////////////////////////////////////////////////////////////////////////////////
613/// It returns the error along Y at point `i`.
614
616{
617 if (i < 0 || i >= fNpoints) return -1;
618 if (fEY) return fEY[i];
619 return -1;
620}
621
622
623////////////////////////////////////////////////////////////////////////////////
624/// It returns the error along X at point `i`. For TGraphErrors this method is
625/// the same as GetErrorX.
626
628{
629 if (i < 0 || i >= fNpoints) return -1;
630 if (fEX) return fEX[i];
631 return -1;
632}
633
634
635////////////////////////////////////////////////////////////////////////////////
636/// It returns the error along X at point `i`. For TGraphErrors this method is
637/// the same as GetErrorX.
638
640{
641 if (i < 0 || i >= fNpoints) return -1;
642 if (fEX) return fEX[i];
643 return -1;
644}
645
646
647////////////////////////////////////////////////////////////////////////////////
648/// It returns the error along Y at point `i`. For TGraphErrors this method is
649/// the same as GetErrorY.
650
652{
653 if (i < 0 || i >= fNpoints) return -1;
654 if (fEY) return fEY[i];
655 return -1;
656}
657
658
659////////////////////////////////////////////////////////////////////////////////
660/// It returns the error along Y at point `i`. For TGraphErrors this method is
661/// the same as GetErrorY.
662
664{
665 if (i < 0 || i >= fNpoints) return -1;
666 if (fEY) return fEY[i];
667 return -1;
668}
669
670////////////////////////////////////////////////////////////////////////////////
671/// Adds all graphs with errors from the collection to this graph.
672/// Returns the total number of points in the result or -1 in case of an error.
673
675{
676 TIter next(li);
677 while (TObject* o = next()) {
678 TGraph *g = dynamic_cast<TGraph*>(o);
679 if (!g) {
680 Error("Merge",
681 "Cannot merge - an object which doesn't inherit from TGraph found in the list");
682 return -1;
683 }
684 int n0 = GetN();
685 int n1 = n0+g->GetN();
686 Set(n1);
687 Double_t * x = g->GetX();
688 Double_t * y = g->GetY();
689 Double_t * ex = g->GetEX();
690 Double_t * ey = g->GetEY();
691 for (Int_t i = 0 ; i < g->GetN(); i++) {
692 SetPoint(n0+i, x[i], y[i]);
693 if (ex) fEX[n0+i] = ex[i];
694 if (ey) fEY[n0+i] = ey[i];
695 }
696 }
697 return GetN();
698}
699
700////////////////////////////////////////////////////////////////////////////////
701/// Print graph and errors values.
702
704{
705 for (Int_t i = 0; i < fNpoints; i++) {
706 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]);
707 }
708}
709
710
711////////////////////////////////////////////////////////////////////////////////
712/// Save primitive as a C++ statement(s) on output stream out
713
714void TGraphErrors::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
715{
716 out << " " << std::endl;
717 static Int_t frameNumber = 1000;
718 frameNumber++;
719
720 auto fXName = SaveArray(out, "fx", frameNumber, fX);
721 auto fYName = SaveArray(out, "fy", frameNumber, fY);
722 auto fEXName = SaveArray(out, "fex", frameNumber, fEX);
723 auto fEYName = SaveArray(out, "fey", frameNumber, fEY);
724
725 if (gROOT->ClassSaved(TGraphErrors::Class()))
726 out << " ";
727 else
728 out << " TGraphErrors *";
729 out << "gre = new TGraphErrors(" << fNpoints << ","
730 << fXName << "," << fYName << ","
731 << fEXName << "," << fEYName << ");"
732 << std::endl;
733
734 SaveHistogramAndFunctions(out, "gre", frameNumber, option);
735}
736
737////////////////////////////////////////////////////////////////////////////////
738/// Multiply the values and errors of a TGraphErrors by a constant c1.
739///
740/// If option contains "x" the x values and errors are scaled
741/// If option contains "y" the y values and errors are scaled
742/// If option contains "xy" both x and y values and errors are scaled
743
745{
747 TString opt = option; opt.ToLower();
748 if (opt.Contains("x") && GetEX()) {
749 for (Int_t i=0; i<GetN(); i++)
750 GetEX()[i] *= c1;
751 }
752 if (opt.Contains("y") && GetEY()) {
753 for (Int_t i=0; i<GetN(); i++)
754 GetEY()[i] *= c1;
755 }
756}
757
758////////////////////////////////////////////////////////////////////////////////
759/// Set `ex` and `ey` values for point pointed by the mouse.
760
762{
763 if (!gPad) {
764 Error("SetPointError", "Cannot be used without gPad, requires last mouse position");
765 return;
766 }
767
768 Int_t px = gPad->GetEventX();
769 Int_t py = gPad->GetEventY();
770
771 //localize point to be deleted
772 Int_t ipoint = -2;
773 Int_t i;
774 // start with a small window (in case the mouse is very close to one point)
775 for (i = 0; i < fNpoints; i++) {
776 Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
777 Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
778 if (dpx * dpx + dpy * dpy < 25) {
779 ipoint = i;
780 break;
781 }
782 }
783 if (ipoint == -2) return;
784
785 fEX[ipoint] = ex;
786 fEY[ipoint] = ey;
787 gPad->Modified();
788}
789
790
791////////////////////////////////////////////////////////////////////////////////
792/// Set `ex` and `ey` values for point number i.
793
795{
796 if (i < 0) return;
797 if (i >= fNpoints) {
798 // re-allocate the object
799 TGraphErrors::SetPoint(i, 0, 0);
800 }
801 fEX[i] = ex;
802 fEY[i] = ey;
803}
804
805
806////////////////////////////////////////////////////////////////////////////////
807/// Stream an object of class TGraphErrors.
808
810{
811 if (b.IsReading()) {
812 UInt_t R__s, R__c;
813 Version_t R__v = b.ReadVersion(&R__s, &R__c);
814 if (R__v > 2) {
815 b.ReadClassBuffer(TGraphErrors::Class(), this, R__v, R__s, R__c);
816 return;
817 }
818 //====process old versions before automatic schema evolution
820 fEX = new Double_t[fNpoints];
821 fEY = new Double_t[fNpoints];
822 if (R__v < 2) {
823 Float_t *ex = new Float_t[fNpoints];
824 Float_t *ey = new Float_t[fNpoints];
825 b.ReadFastArray(ex, fNpoints);
826 b.ReadFastArray(ey, fNpoints);
827 for (Int_t i = 0; i < fNpoints; i++) {
828 fEX[i] = ex[i];
829 fEY[i] = ey[i];
830 }
831 delete [] ey;
832 delete [] ex;
833 } else {
834 b.ReadFastArray(fEX, fNpoints);
835 b.ReadFastArray(fEY, fNpoints);
836 }
837 b.CheckByteCount(R__s, R__c, TGraphErrors::IsA());
838 //====end of old versions
839
840 } else {
841 b.WriteClassBuffer(TGraphErrors::Class(), this);
842 }
843}
844
845////////////////////////////////////////////////////////////////////////////////
846/// Swap points.
847
849{
850 SwapValues(fEX, pos1, pos2);
851 SwapValues(fEY, pos1, pos2);
852 TGraph::SwapPoints(pos1, pos2);
853}
854
855////////////////////////////////////////////////////////////////////////////////
856/// Update the fX, fY, fEX, and fEY arrays with the sorted values.
857
858void TGraphErrors::UpdateArrays(const std::vector<Int_t> &sorting_indices, Int_t numSortedPoints, Int_t low)
859{
860 std::vector<Double_t> fEXSorted(numSortedPoints);
861 std::vector<Double_t> fEYSorted(numSortedPoints);
862
863 // Fill the sorted X and Y error values based on the sorted indices
864 std::generate(fEXSorted.begin(), fEXSorted.end(),
865 [begin = low, &sorting_indices, this]() mutable { return fEX[sorting_indices[begin++]]; });
866 std::generate(fEYSorted.begin(), fEYSorted.end(),
867 [begin = low, &sorting_indices, this]() mutable { return fEY[sorting_indices[begin++]]; });
868
869 // Copy the sorted X and Y error values back to the original arrays
870 std::copy(fEXSorted.begin(), fEXSorted.end(), fEX + low);
871 std::copy(fEYSorted.begin(), fEYSorted.end(), fEY + low);
872
873 TGraph::UpdateArrays(sorting_indices, numSortedPoints, low);
874}
#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:406
R__EXTERN TStyle * gStyle
Definition TStyle.h:433
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].
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()
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:2319
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:2177
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:2569
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:2153
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:709
virtual void Scale(Double_t c1=1., Option_t *option="y")
Multiply the values of a TGraph by a constant c1.
Definition TGraph.cxx:2236
static void SwapValues(Double_t *arr, Int_t pos1, Int_t pos2)
Swap values.
Definition TGraph.cxx:2588
void Streamer(TBuffer &) override
Stream an object of class TGraph.
Definition TGraph.cxx:2493
virtual Bool_t DoMerge(const TGraph *g)
protected function to perform the merge operation of a graph
Definition TGraph.cxx:2653
virtual void SwapPoints(Int_t pos1, Int_t pos2)
Swap points.
Definition TGraph.cxx:2560
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:1080
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:2254
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:1511
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:757
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:962
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:976
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:185
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