31 ClassImp(TGraphErrors);
70 TGraphErrors::TGraphErrors(): TGraph()
72 if (!CtorAllocate())
return;
81 TGraphErrors::TGraphErrors(Int_t n)
84 if (!CtorAllocate())
return;
85 FillZero(0, fNpoints);
94 TGraphErrors::TGraphErrors(Int_t n,
const Float_t *x,
const Float_t *y,
const Float_t *ex,
const Float_t *ey)
97 if (!CtorAllocate())
return;
99 for (Int_t i = 0; i < n; i++) {
100 if (ex) fEX[i] = ex[i];
102 if (ey) fEY[i] = ey[i];
113 TGraphErrors::TGraphErrors(Int_t n,
const Double_t *x,
const Double_t *y,
const Double_t *ex,
const Double_t *ey)
116 if (!CtorAllocate())
return;
118 n =
sizeof(Double_t) * fNpoints;
119 if (ex) memcpy(fEX, ex, n);
120 else memset(fEX, 0, n);
121 if (ey) memcpy(fEY, ey, n);
122 else memset(fEY, 0, n);
133 TGraphErrors::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() )
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);
153 TGraphErrors::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() )
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);
169 TGraphErrors::TGraphErrors(
const TGraphErrors &gr)
172 if (!CtorAllocate())
return;
174 Int_t n =
sizeof(Double_t) * fNpoints;
175 memcpy(fEX, gr.fEX, n);
176 memcpy(fEY, gr.fEY, n);
183 TGraphErrors& TGraphErrors::operator=(
const TGraphErrors &gr)
186 TGraph::operator=(gr);
188 if (fEX)
delete [] fEX;
189 if (fEY)
delete [] fEY;
190 if (!CtorAllocate())
return *
this;
192 Int_t n =
sizeof(Double_t) * fNpoints;
193 memcpy(fEX, gr.fEX, n);
194 memcpy(fEY, gr.fEY, n);
203 TGraphErrors::TGraphErrors(
const TH1 *h)
206 if (!CtorAllocate())
return;
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);
231 TGraphErrors::TGraphErrors(
const char *filename,
const char *format, Option_t *option)
234 if (!CtorAllocate())
return;
235 Double_t x, y, ex, ey;
236 TString fname = filename;
237 gSystem->ExpandPathName(fname);
238 std::ifstream infile(fname.Data());
239 if (!infile.good()) {
241 Error(
"TGraphErrors",
"Cannot open file: %s, TGraphErrors is Zombie", filename);
248 if (strcmp(option,
"") == 0) {
250 Int_t ncol = CalculateScanfFields(format);
252 while (std::getline(infile, line,
'\n')) {
255 res = sscanf(line.c_str(), format, &x, &y);
256 }
else if (ncol < 4) {
257 res = sscanf(line.c_str(), format, &x, &y, &ey);
259 res = sscanf(line.c_str(), format, &x, &y, &ex, &ey);
265 SetPointError(np, ex, ey);
273 TString format_ = TString(format) ;
274 format_.ReplaceAll(
" ",
"") ;
275 format_.ReplaceAll(
"\t",
"") ;
276 format_.ReplaceAll(
"lg",
"") ;
277 format_.ReplaceAll(
"s",
"") ;
278 format_.ReplaceAll(
"%*",
"0") ;
279 format_.ReplaceAll(
"%",
"1") ;
280 if (!format_.IsDigit()) {
281 Error(
"TGraphErrors",
"Incorrect input format! Allowed format tags are {\"%%lg\",\"%%*lg\" or \"%%*s\"}");
284 Int_t ntokens = format_.Length() ;
286 Error(
"TGraphErrors",
"Incorrect input format! Only %d tag(s) in format whereas at least 2 \"%%lg\" tags are expected!", ntokens);
289 Int_t ntokensToBeSaved = 0 ;
290 Bool_t * isTokenToBeSaved =
new Bool_t [ntokens] ;
291 for (Int_t idx = 0; idx < ntokens; idx++) {
292 isTokenToBeSaved[idx] = TString::Format(
"%c", format_[idx]).Atoi() ;
293 if (isTokenToBeSaved[idx] == 1) {
297 if (ntokens >= 2 && (ntokensToBeSaved < 2 || ntokensToBeSaved > 4)) {
298 Error(
"TGraphErrors",
"Incorrect input format! There are %d \"%%lg\" tag(s) in format whereas 2,3 or 4 are expected!", ntokensToBeSaved);
299 delete [] isTokenToBeSaved ;
304 Bool_t isLineToBeSkipped = kFALSE ;
305 char * token = NULL ;
306 TString token_str =
"" ;
307 Int_t token_idx = 0 ;
308 Double_t * value =
new Double_t [4] ;
309 for (Int_t k = 0; k < 4; k++) {
312 Int_t value_idx = 0 ;
316 while (std::getline(infile, line,
'\n')) {
318 if (line[line.size() - 1] == char(13)) {
319 line.erase(line.end() - 1, line.end()) ;
321 token = R__STRTOK_R(const_cast<char *>(line.c_str()), option, &rest);
322 while (token != NULL && value_idx < ntokensToBeSaved) {
323 if (isTokenToBeSaved[token_idx]) {
324 token_str = TString(token) ;
325 token_str.ReplaceAll(
"\t",
"") ;
326 if (!token_str.IsFloat()) {
327 isLineToBeSkipped = kTRUE ;
330 value[value_idx] = token_str.Atof() ;
334 token = R__STRTOK_R(NULL, option, &rest);
337 if (!isLineToBeSkipped && value_idx > 1) {
343 SetPointError(np, ex, ey);
347 isLineToBeSkipped = kFALSE ;
355 delete [] isTokenToBeSaved ;
366 TGraphErrors::~TGraphErrors()
386 void TGraphErrors::Apply(TF1 *f)
388 Double_t x, y, ex, ey;
394 for (Int_t i = 0; i < GetN(); i++) {
399 SetPoint(i, x, f->Eval(x, y));
400 SetPointError(i, ex, TMath::Abs(f->Eval(x, y + ey) - f->Eval(x, y - ey)) / 2.);
402 if (gPad) gPad->Modified();
409 Int_t TGraphErrors::CalculateScanfFields(
const char *fmt)
412 while ((fmt = strchr(fmt,
'%'))) {
413 Bool_t skip = kFALSE;
416 if (*++fmt &&
'^' == *fmt) ++fmt;
417 if (*++fmt &&
']' == *fmt) ++fmt;
418 while (*fmt && *fmt !=
']')
423 if (
'%' == *fmt)
break;
426 }
else if (strchr(
"dDiouxXxfegEscpn", *fmt)) {
440 void TGraphErrors::ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax)
const
442 TGraph::ComputeRange(xmin, ymin, xmax, ymax);
444 for (Int_t i = 0; i < fNpoints; i++) {
445 if (fX[i] - fEX[i] < xmin) {
446 if (gPad && gPad->GetLogx()) {
447 if (fEX[i] < fX[i]) xmin = fX[i] - fEX[i];
448 else xmin = TMath::Min(xmin, fX[i] / 3);
450 xmin = fX[i] - fEX[i];
453 if (fX[i] + fEX[i] > xmax) xmax = fX[i] + fEX[i];
454 if (fY[i] - fEY[i] < ymin) {
455 if (gPad && gPad->GetLogy()) {
456 if (fEY[i] < fY[i]) ymin = fY[i] - fEY[i];
457 else ymin = TMath::Min(ymin, fY[i] / 3);
459 ymin = fY[i] - fEY[i];
462 if (fY[i] + fEY[i] > ymax) ymax = fY[i] + fEY[i];
470 void TGraphErrors::CopyAndRelease(Double_t **newarrays,
471 Int_t ibegin, Int_t iend, Int_t obegin)
473 CopyPoints(newarrays, ibegin, iend, obegin);
492 Bool_t TGraphErrors::CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend,
495 if (TGraph::CopyPoints(arrays ? arrays + 2 : 0, ibegin, iend, obegin)) {
496 Int_t n = (iend - ibegin) *
sizeof(Double_t);
498 memmove(&arrays[0][obegin], &fEX[ibegin], n);
499 memmove(&arrays[1][obegin], &fEY[ibegin], n);
501 memmove(&fEX[obegin], &fEX[ibegin], n);
502 memmove(&fEY[obegin], &fEY[ibegin], n);
516 Bool_t TGraphErrors::CtorAllocate()
523 fEX =
new Double_t[fMaxSize];
524 fEY =
new Double_t[fMaxSize];
532 Bool_t TGraphErrors::DoMerge(
const TGraph *g)
534 if (g->GetN() == 0)
return kFALSE;
536 Double_t * ex = g->GetEX();
537 Double_t * ey = g->GetEY();
538 if (ex == 0 || ey == 0 ) {
539 if (g->IsA() != TGraph::Class() )
540 Warning(
"DoMerge",
"Merging a %s is not compatible with a TGraphErrors - errors will be ignored",g->IsA()->GetName());
541 return TGraph::DoMerge(g);
543 for (Int_t i = 0 ; i < g->GetN(); i++) {
544 Int_t ipoint = GetN();
545 Double_t x = g->GetX()[i];
546 Double_t y = g->GetY()[i];
547 SetPoint(ipoint, x, y);
548 SetPointError( ipoint, ex[i], ey[i] );
557 void TGraphErrors::FillZero(Int_t begin, Int_t end, Bool_t from_ctor)
560 TGraph::FillZero(begin, end, from_ctor);
562 Int_t n = (end - begin) *
sizeof(Double_t);
563 memset(fEX + begin, 0, n);
564 memset(fEY + begin, 0, n);
572 Double_t TGraphErrors::GetErrorX(Int_t i)
const
574 if (i < 0 || i >= fNpoints)
return -1;
575 if (fEX)
return fEX[i];
584 Double_t TGraphErrors::GetErrorY(Int_t i)
const
586 if (i < 0 || i >= fNpoints)
return -1;
587 if (fEY)
return fEY[i];
596 Double_t TGraphErrors::GetErrorXhigh(Int_t i)
const
598 if (i < 0 || i >= fNpoints)
return -1;
599 if (fEX)
return fEX[i];
608 Double_t TGraphErrors::GetErrorXlow(Int_t i)
const
610 if (i < 0 || i >= fNpoints)
return -1;
611 if (fEX)
return fEX[i];
620 Double_t TGraphErrors::GetErrorYhigh(Int_t i)
const
622 if (i < 0 || i >= fNpoints)
return -1;
623 if (fEY)
return fEY[i];
632 Double_t TGraphErrors::GetErrorYlow(Int_t i)
const
634 if (i < 0 || i >= fNpoints)
return -1;
635 if (fEY)
return fEY[i];
643 Int_t TGraphErrors::Merge(TCollection* li)
646 while (TObject* o = next()) {
647 TGraph *g =
dynamic_cast<TGraph*
>(o);
650 "Cannot merge - an object which doesn't inherit from TGraph found in the list");
654 int n1 = n0+g->GetN();
656 Double_t * x = g->GetX();
657 Double_t * y = g->GetY();
658 Double_t * ex = g->GetEX();
659 Double_t * ey = g->GetEY();
660 for (Int_t i = 0 ; i < g->GetN(); i++) {
661 SetPoint(n0+i, x[i], y[i]);
662 if (ex) fEX[n0+i] = ex[i];
663 if (ey) fEY[n0+i] = ey[i];
672 void TGraphErrors::Print(Option_t *)
const
674 for (Int_t i = 0; i < fNpoints; i++) {
675 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]);
683 void TGraphErrors::SavePrimitive(std::ostream &out, Option_t *option )
686 out <<
" " << std::endl;
687 static Int_t frameNumber = 1000;
691 TString fXName = TString(GetName()) + Form(
"_fx%d",frameNumber);
692 TString fYName = TString(GetName()) + Form(
"_fy%d",frameNumber);
693 TString fEXName = TString(GetName()) + Form(
"_fex%d",frameNumber);
694 TString fEYName = TString(GetName()) + Form(
"_fey%d",frameNumber);
695 out <<
" Double_t " << fXName <<
"[" << fNpoints <<
"] = {" << std::endl;
696 for (i = 0; i < fNpoints-1; i++) out <<
" " << fX[i] <<
"," << std::endl;
697 out <<
" " << fX[fNpoints-1] <<
"};" << std::endl;
698 out <<
" Double_t " << fYName <<
"[" << fNpoints <<
"] = {" << std::endl;
699 for (i = 0; i < fNpoints-1; i++) out <<
" " << fY[i] <<
"," << std::endl;
700 out <<
" " << fY[fNpoints-1] <<
"};" << std::endl;
701 out <<
" Double_t " << fEXName <<
"[" << fNpoints <<
"] = {" << std::endl;
702 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEX[i] <<
"," << std::endl;
703 out <<
" " << fEX[fNpoints-1] <<
"};" << std::endl;
704 out <<
" Double_t " << fEYName <<
"[" << fNpoints <<
"] = {" << std::endl;
705 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEY[i] <<
"," << std::endl;
706 out <<
" " << fEY[fNpoints-1] <<
"};" << std::endl;
708 if (gROOT->ClassSaved(TGraphErrors::Class())) out <<
" ";
709 else out <<
" TGraphErrors *";
710 out <<
"gre = new TGraphErrors(" << fNpoints <<
","
711 << fXName <<
"," << fYName <<
","
712 << fEXName <<
"," << fEYName <<
");"
715 out <<
" gre->SetName(" << quote << GetName() << quote <<
");" << std::endl;
716 out <<
" gre->SetTitle(" << quote << GetTitle() << quote <<
");" << std::endl;
718 SaveFillAttributes(out,
"gre", 0, 1001);
719 SaveLineAttributes(out,
"gre", 1, 1, 1);
720 SaveMarkerAttributes(out,
"gre", 1, 1, 1);
723 TString hname = fHistogram->GetName();
724 hname += frameNumber;
725 fHistogram->SetName(Form(
"Graph_%s", hname.Data()));
726 fHistogram->SavePrimitive(out,
"nodraw");
727 out <<
" gre->SetHistogram(" << fHistogram->GetName() <<
");" << std::endl;
728 out <<
" " << std::endl;
732 TIter next(fFunctions);
734 while ((obj = next())) {
735 obj->SavePrimitive(out, Form(
"nodraw #%d\n",++frameNumber));
736 if (obj->InheritsFrom(
"TPaveStats")) {
737 out <<
" gre->GetListOfFunctions()->Add(ptstats);" << std::endl;
738 out <<
" ptstats->SetParent(gre->GetListOfFunctions());" << std::endl;
741 objname.Form(
"%s%d",obj->GetName(),frameNumber);
742 if (obj->InheritsFrom(
"TF1")) {
743 out <<
" " << objname <<
"->SetParent(gre);\n";
745 out <<
" gre->GetListOfFunctions()->Add("
746 << objname <<
");" << std::endl;
750 const char *l = strstr(option,
"multigraph");
752 out <<
" multigraph->Add(gre," << quote << l + 10 << quote <<
");" << std::endl;
754 out <<
" gre->Draw(" << quote << option << quote <<
");" << std::endl;
762 void TGraphErrors::SetPointError(Double_t ex, Double_t ey)
764 Int_t px = gPad->GetEventX();
765 Int_t py = gPad->GetEventY();
771 for (i = 0; i < fNpoints; i++) {
772 Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
773 Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
774 if (dpx * dpx + dpy * dpy < 25) {
779 if (ipoint == -2)
return;
790 void TGraphErrors::SetPointError(Int_t i, Double_t ex, Double_t ey)
795 TGraphErrors::SetPoint(i, 0, 0);
805 void TGraphErrors::Streamer(TBuffer &b)
809 Version_t R__v = b.ReadVersion(&R__s, &R__c);
811 b.ReadClassBuffer(TGraphErrors::Class(),
this, R__v, R__s, R__c);
816 fEX =
new Double_t[fNpoints];
817 fEY =
new Double_t[fNpoints];
819 Float_t *ex =
new Float_t[fNpoints];
820 Float_t *ey =
new Float_t[fNpoints];
821 b.ReadFastArray(ex, fNpoints);
822 b.ReadFastArray(ey, fNpoints);
823 for (Int_t i = 0; i < fNpoints; i++) {
830 b.ReadFastArray(fEX, fNpoints);
831 b.ReadFastArray(fEY, fNpoints);
833 b.CheckByteCount(R__s, R__c, TGraphErrors::IsA());
837 b.WriteClassBuffer(TGraphErrors::Class(),
this);
845 void TGraphErrors::SwapPoints(Int_t pos1, Int_t pos2)
847 SwapValues(fEX, pos1, pos2);
848 SwapValues(fEY, pos1, pos2);
849 TGraph::SwapPoints(pos1, pos2);