26 ClassImp(TGraphBentErrors);
66 TGraphBentErrors::TGraphBentErrors(): TGraph()
68 if (!CtorAllocate())
return;
75 TGraphBentErrors::TGraphBentErrors(
const TGraphBentErrors &gr)
78 if (!CtorAllocate())
return;
79 Int_t n = fNpoints*
sizeof(Double_t);
80 memcpy(fEXlow, gr.fEXlow, n);
81 memcpy(fEYlow, gr.fEYlow, n);
82 memcpy(fEXhigh, gr.fEXhigh, n);
83 memcpy(fEYhigh, gr.fEYhigh, n);
84 memcpy(fEXlowd, gr.fEXlowd, n);
85 memcpy(fEYlowd, gr.fEYlowd, n);
86 memcpy(fEXhighd, gr.fEXhighd, n);
87 memcpy(fEYhighd, gr.fEYhighd, n);
96 TGraphBentErrors::TGraphBentErrors(Int_t n)
99 if (!CtorAllocate())
return;
100 FillZero(0, fNpoints);
109 TGraphBentErrors::TGraphBentErrors(Int_t n,
110 const Float_t *x,
const Float_t *y,
111 const Float_t *exl,
const Float_t *exh,
112 const Float_t *eyl,
const Float_t *eyh,
113 const Float_t *exld,
const Float_t *exhd,
114 const Float_t *eyld,
const Float_t *eyhd)
117 if (!CtorAllocate())
return;
119 for (Int_t i=0;i<n;i++) {
120 if (exl) fEXlow[i] = exl[i];
122 if (exh) fEXhigh[i] = exh[i];
124 if (eyl) fEYlow[i] = eyl[i];
126 if (eyh) fEYhigh[i] = eyh[i];
129 if (exld) fEXlowd[i] = exld[i];
131 if (exhd) fEXhighd[i] = exhd[i];
132 else fEXhighd[i] = 0;
133 if (eyld) fEYlowd[i] = eyld[i];
135 if (eyhd) fEYhighd[i] = eyhd[i];
136 else fEYhighd[i] = 0;
146 TGraphBentErrors::TGraphBentErrors(Int_t n,
147 const Double_t *x,
const Double_t *y,
148 const Double_t *exl,
const Double_t *exh,
149 const Double_t *eyl,
const Double_t *eyh,
150 const Double_t *exld,
const Double_t *exhd,
151 const Double_t *eyld,
const Double_t *eyhd)
154 if (!CtorAllocate())
return;
155 n =
sizeof(Double_t)*fNpoints;
157 if (exl) memcpy(fEXlow, exl, n);
158 else memset(fEXlow, 0, n);
159 if (exh) memcpy(fEXhigh, exh, n);
160 else memset(fEXhigh, 0, n);
161 if (eyl) memcpy(fEYlow, eyl, n);
162 else memset(fEYlow, 0, n);
163 if (eyh) memcpy(fEYhigh, eyh, n);
164 else memset(fEYhigh, 0, n);
166 if (exld) memcpy(fEXlowd, exld, n);
167 else memset(fEXlowd, 0, n);
168 if (exhd) memcpy(fEXhighd, exhd, n);
169 else memset(fEXhighd, 0, n);
170 if (eyld) memcpy(fEYlowd, eyld, n);
171 else memset(fEYlowd, 0, n);
172 if (eyhd) memcpy(fEYhighd, eyhd, n);
173 else memset(fEYhighd, 0, n);
180 TGraphBentErrors::~TGraphBentErrors()
205 void TGraphBentErrors::Apply(TF1 *f)
207 Double_t x,y,exl,exh,eyl,eyh,eyl_new,eyh_new,fxy;
213 for (Int_t i=0;i<GetN();i++) {
216 exh=GetErrorXhigh(i);
218 eyh=GetErrorYhigh(i);
225 if (f->Eval(x,y-eyl)<f->Eval(x,y+eyh)) {
226 eyl_new = TMath::Abs(fxy - f->Eval(x,y-eyl));
227 eyh_new = TMath::Abs(f->Eval(x,y+eyh) - fxy);
230 eyh_new = TMath::Abs(fxy - f->Eval(x,y-eyl));
231 eyl_new = TMath::Abs(f->Eval(x,y+eyh) - fxy);
235 SetPointError(i,exl,exh,eyl_new,eyh_new);
237 if (gPad) gPad->Modified();
244 void TGraphBentErrors::ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax)
const
246 TGraph::ComputeRange(xmin,ymin,xmax,ymax);
248 for (Int_t i=0;i<fNpoints;i++) {
249 if (fX[i] -fEXlow[i] < xmin) {
250 if (gPad && gPad->GetLogx()) {
251 if (fEXlow[i] < fX[i]) xmin = fX[i]-fEXlow[i];
252 else xmin = TMath::Min(xmin,fX[i]/3);
254 xmin = fX[i]-fEXlow[i];
257 if (fX[i] +fEXhigh[i] > xmax) xmax = fX[i]+fEXhigh[i];
258 if (fY[i] -fEYlow[i] < ymin) {
259 if (gPad && gPad->GetLogy()) {
260 if (fEYlow[i] < fY[i]) ymin = fY[i]-fEYlow[i];
261 else ymin = TMath::Min(ymin,fY[i]/3);
263 ymin = fY[i]-fEYlow[i];
266 if (fY[i] +fEYhigh[i] > ymax) ymax = fY[i]+fEYhigh[i];
274 void TGraphBentErrors::CopyAndRelease(Double_t **newarrays,
275 Int_t ibegin, Int_t iend, Int_t obegin)
277 CopyPoints(newarrays, ibegin, iend, obegin);
280 fEXlow = newarrays[0];
282 fEXhigh = newarrays[1];
284 fEYlow = newarrays[2];
286 fEYhigh = newarrays[3];
288 fEXlowd = newarrays[4];
290 fEXhighd = newarrays[5];
292 fEYlowd = newarrays[6];
294 fEYhighd = newarrays[7];
308 Bool_t TGraphBentErrors::CopyPoints(Double_t **arrays,
309 Int_t ibegin, Int_t iend, Int_t obegin)
311 if (TGraph::CopyPoints(arrays ? arrays+8 : 0, ibegin, iend, obegin)) {
312 Int_t n = (iend - ibegin)*
sizeof(Double_t);
314 memmove(&arrays[0][obegin], &fEXlow[ibegin], n);
315 memmove(&arrays[1][obegin], &fEXhigh[ibegin], n);
316 memmove(&arrays[2][obegin], &fEYlow[ibegin], n);
317 memmove(&arrays[3][obegin], &fEYhigh[ibegin], n);
318 memmove(&arrays[4][obegin], &fEXlowd[ibegin], n);
319 memmove(&arrays[5][obegin], &fEXhighd[ibegin], n);
320 memmove(&arrays[6][obegin], &fEYlowd[ibegin], n);
321 memmove(&arrays[7][obegin], &fEYhighd[ibegin], n);
323 memmove(&fEXlow[obegin], &fEXlow[ibegin], n);
324 memmove(&fEXhigh[obegin], &fEXhigh[ibegin], n);
325 memmove(&fEYlow[obegin], &fEYlow[ibegin], n);
326 memmove(&fEYhigh[obegin], &fEYhigh[ibegin], n);
327 memmove(&fEXlowd[obegin], &fEXlowd[ibegin], n);
328 memmove(&fEXhighd[obegin], &fEXhighd[ibegin], n);
329 memmove(&fEYlowd[obegin], &fEYlowd[ibegin], n);
330 memmove(&fEYhighd[obegin], &fEYhighd[ibegin], n);
342 Bool_t TGraphBentErrors::CtorAllocate(
void)
345 fEXlow = fEYlow = fEXhigh = fEYhigh = 0;
346 fEXlowd = fEYlowd = fEXhighd = fEYhighd = 0;
349 fEXlow =
new Double_t[fMaxSize];
350 fEYlow =
new Double_t[fMaxSize];
351 fEXhigh =
new Double_t[fMaxSize];
352 fEYhigh =
new Double_t[fMaxSize];
353 fEXlowd =
new Double_t[fMaxSize];
354 fEYlowd =
new Double_t[fMaxSize];
355 fEXhighd =
new Double_t[fMaxSize];
356 fEYhighd =
new Double_t[fMaxSize];
363 Bool_t TGraphBentErrors::DoMerge(
const TGraph *g)
365 if (g->GetN() == 0)
return kFALSE;
367 Double_t * exl = g->GetEXlow();
368 Double_t * exh = g->GetEXhigh();
369 Double_t * eyl = g->GetEYlow();
370 Double_t * eyh = g->GetEYhigh();
372 Double_t * exld = g->GetEXlowd();
373 Double_t * exhd = g->GetEXhighd();
374 Double_t * eyld = g->GetEYlowd();
375 Double_t * eyhd = g->GetEYhighd();
377 if (exl == 0 || exh == 0 || eyl == 0 || eyh == 0 ||
378 exld == 0 || exhd == 0 || eyld == 0 || eyhd == 0) {
379 if (g->IsA() != TGraph::Class() )
380 Warning(
"DoMerge",
"Merging a %s is not compatible with a TGraphBentErrors - errors will be ignored",g->IsA()->GetName());
381 return TGraph::DoMerge(g);
383 for (Int_t i = 0 ; i < g->GetN(); i++) {
384 Int_t ipoint = GetN();
385 Double_t x = g->GetX()[i];
386 Double_t y = g->GetY()[i];
387 SetPoint(ipoint, x, y);
388 SetPointError(ipoint, exl[i], exh[i], eyl[i], eyh[i],
389 exld[i], exhd[i], eyld[i], eyhd[i] );
399 Double_t TGraphBentErrors::GetErrorX(Int_t i)
const
401 if (i < 0 || i >= fNpoints)
return -1;
402 if (!fEXlow && !fEXhigh)
return -1;
403 Double_t elow=0, ehigh=0;
404 if (fEXlow) elow = fEXlow[i];
405 if (fEXhigh) ehigh = fEXhigh[i];
406 return TMath::Sqrt(0.5*(elow*elow + ehigh*ehigh));
414 Double_t TGraphBentErrors::GetErrorY(Int_t i)
const
416 if (i < 0 || i >= fNpoints)
return -1;
417 if (!fEYlow && !fEYhigh)
return -1;
418 Double_t elow=0, ehigh=0;
419 if (fEYlow) elow = fEYlow[i];
420 if (fEYhigh) ehigh = fEYhigh[i];
421 return TMath::Sqrt(0.5*(elow*elow + ehigh*ehigh));
428 Double_t TGraphBentErrors::GetErrorXhigh(Int_t i)
const
430 if (i<0 || i>fNpoints)
return -1;
431 if (fEXhigh)
return fEXhigh[i];
439 Double_t TGraphBentErrors::GetErrorXlow(Int_t i)
const
441 if (i<0 || i>fNpoints)
return -1;
442 if (fEXlow)
return fEXlow[i];
450 Double_t TGraphBentErrors::GetErrorYhigh(Int_t i)
const
452 if (i<0 || i>fNpoints)
return -1;
453 if (fEYhigh)
return fEYhigh[i];
461 Double_t TGraphBentErrors::GetErrorYlow(Int_t i)
const
463 if (i<0 || i>fNpoints)
return -1;
464 if (fEYlow)
return fEYlow[i];
472 void TGraphBentErrors::FillZero(Int_t begin, Int_t end,
476 TGraph::FillZero(begin, end, from_ctor);
478 Int_t n = (end - begin)*
sizeof(Double_t);
479 memset(fEXlow + begin, 0, n);
480 memset(fEXhigh + begin, 0, n);
481 memset(fEYlow + begin, 0, n);
482 memset(fEYhigh + begin, 0, n);
483 memset(fEXlowd + begin, 0, n);
484 memset(fEXhighd + begin, 0, n);
485 memset(fEYlowd + begin, 0, n);
486 memset(fEYhighd + begin, 0, n);
493 void TGraphBentErrors::Print(Option_t *)
const
495 for (Int_t i=0;i<fNpoints;i++) {
496 printf(
"x[%d]=%g, y[%d]=%g, exl[%d]=%g, exh[%d]=%g, eyl[%d]=%g, eyh[%d]=%g\n"
497 ,i,fX[i],i,fY[i],i,fEXlow[i],i,fEXhigh[i],i,fEYlow[i],i,fEYhigh[i]);
505 void TGraphBentErrors::SavePrimitive(std::ostream &out, Option_t *option )
508 out <<
" " << std::endl;
509 static Int_t frameNumber = 2000;
513 TString fXName = TString(GetName()) + Form(
"_fx%d",frameNumber);
514 TString fYName = TString(GetName()) + Form(
"_fy%d",frameNumber);
515 TString fElXName = TString(GetName()) + Form(
"_felx%d",frameNumber);
516 TString fElYName = TString(GetName()) + Form(
"_fely%d",frameNumber);
517 TString fEhXName = TString(GetName()) + Form(
"_fehx%d",frameNumber);
518 TString fEhYName = TString(GetName()) + Form(
"_fehy%d",frameNumber);
519 TString fEldXName = TString(GetName()) + Form(
"_feldx%d",frameNumber);
520 TString fEldYName = TString(GetName()) + Form(
"_feldy%d",frameNumber);
521 TString fEhdXName = TString(GetName()) + Form(
"_fehdx%d",frameNumber);
522 TString fEhdYName = TString(GetName()) + Form(
"_fehdy%d",frameNumber);
523 out <<
" Double_t " << fXName <<
"[" << fNpoints <<
"] = {" << std::endl;
524 for (i = 0; i < fNpoints-1; i++) out <<
" " << fX[i] <<
"," << std::endl;
525 out <<
" " << fX[fNpoints-1] <<
"};" << std::endl;
526 out <<
" Double_t " << fYName <<
"[" << fNpoints <<
"] = {" << std::endl;
527 for (i = 0; i < fNpoints-1; i++) out <<
" " << fY[i] <<
"," << std::endl;
528 out <<
" " << fY[fNpoints-1] <<
"};" << std::endl;
529 out <<
" Double_t " << fElXName <<
"[" << fNpoints <<
"] = {" << std::endl;
530 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEXlow[i] <<
"," << std::endl;
531 out <<
" " << fEXlow[fNpoints-1] <<
"};" << std::endl;
532 out <<
" Double_t " << fElYName <<
"[" << fNpoints <<
"] = {" << std::endl;
533 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEYlow[i] <<
"," << std::endl;
534 out <<
" " << fEYlow[fNpoints-1] <<
"};" << std::endl;
535 out <<
" Double_t " << fEhXName <<
"[" << fNpoints <<
"] = {" << std::endl;
536 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEXhigh[i] <<
"," << std::endl;
537 out <<
" " << fEXhigh[fNpoints-1] <<
"};" << std::endl;
538 out <<
" Double_t " << fEhYName <<
"[" << fNpoints <<
"] = {" << std::endl;
539 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEYhigh[i] <<
"," << std::endl;
540 out <<
" " << fEYhigh[fNpoints-1] <<
"};" << std::endl;
541 out <<
" Double_t " << fEldXName <<
"[" << fNpoints <<
"] = {" << std::endl;
542 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEXlowd[i] <<
"," << std::endl;
543 out <<
" " << fEXlowd[fNpoints-1] <<
"};" << std::endl;
544 out <<
" Double_t " << fEldYName <<
"[" << fNpoints <<
"] = {" << std::endl;
545 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEYlowd[i] <<
"," << std::endl;
546 out <<
" " << fEYlowd[fNpoints-1] <<
"};" << std::endl;
547 out <<
" Double_t " << fEhdXName <<
"[" << fNpoints <<
"] = {" << std::endl;
548 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEXhighd[i] <<
"," << std::endl;
549 out <<
" " << fEXhighd[fNpoints-1] <<
"};" << std::endl;
550 out <<
" Double_t " << fEhdYName <<
"[" << fNpoints <<
"] = {" << std::endl;
551 for (i = 0; i < fNpoints-1; i++) out <<
" " << fEYhighd[i] <<
"," << std::endl;
552 out <<
" " << fEYhighd[fNpoints-1] <<
"};" << std::endl;
554 if (gROOT->ClassSaved(TGraphBentErrors::Class())) out <<
" ";
555 else out <<
" TGraphBentErrors *";
556 out <<
"grbe = new TGraphBentErrors("<< fNpoints <<
","
557 << fXName <<
"," << fYName <<
","
558 << fElXName <<
"," << fEhXName <<
","
559 << fElYName <<
"," << fEhYName <<
","
560 << fEldXName <<
"," << fEhdXName <<
","
561 << fEldYName <<
"," << fEhdYName <<
");"
564 out <<
" grbe->SetName(" << quote << GetName() << quote <<
");" << std::endl;
565 out <<
" grbe->SetTitle(" << quote << GetTitle() << quote <<
");" << std::endl;
567 SaveFillAttributes(out,
"grbe",0,1001);
568 SaveLineAttributes(out,
"grbe",1,1,1);
569 SaveMarkerAttributes(out,
"grbe",1,1,1);
572 TString hname = fHistogram->GetName();
573 hname += frameNumber;
574 fHistogram->SetName(Form(
"Graph_%s",hname.Data()));
575 fHistogram->SavePrimitive(out,
"nodraw");
576 out<<
" grbe->SetHistogram("<<fHistogram->GetName()<<
");"<<std::endl;
581 TIter next(fFunctions);
583 while ((obj = next())) {
584 obj->SavePrimitive(out, Form(
"nodraw #%d\n",++frameNumber));
585 if (obj->InheritsFrom(
"TPaveStats")) {
586 out <<
" grbe->GetListOfFunctions()->Add(ptstats);" << std::endl;
587 out <<
" ptstats->SetParent(grbe->GetListOfFunctions());" << std::endl;
590 objname.Form(
"%s%d",obj->GetName(),frameNumber);
591 if (obj->InheritsFrom(
"TF1")) {
592 out <<
" " << objname <<
"->SetParent(grbe);\n";
594 out <<
" grbe->GetListOfFunctions()->Add("
595 << objname <<
");" << std::endl;
599 const char *l = strstr(option,
"multigraph");
601 out<<
" multigraph->Add(grbe,"<<quote<<l+10<<quote<<
");"<<std::endl;
603 out<<
" grbe->Draw("<<quote<<option<<quote<<
");"<<std::endl;
611 void TGraphBentErrors::SetPointError(Double_t exl, Double_t exh, Double_t eyl, Double_t eyh,
612 Double_t exld, Double_t exhd, Double_t eyld, Double_t eyhd)
614 Int_t px = gPad->GetEventX();
615 Int_t py = gPad->GetEventY();
621 for (i=0;i<fNpoints;i++) {
622 Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
623 Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
624 if (dpx*dpx+dpy*dpy < 25) {ipoint = i;
break;}
626 if (ipoint == -2)
return;
628 fEXlow[ipoint] = exl;
629 fEYlow[ipoint] = eyl;
630 fEXhigh[ipoint] = exh;
631 fEYhigh[ipoint] = eyh;
632 fEXlowd[ipoint] = exld;
633 fEXhighd[ipoint] = exhd;
634 fEYlowd[ipoint] = eyld;
635 fEYhighd[ipoint] = eyhd;
643 void TGraphBentErrors::SetPointError(Int_t i, Double_t exl, Double_t exh, Double_t eyl, Double_t eyh,
644 Double_t exld, Double_t exhd, Double_t eyld, Double_t eyhd)
649 TGraphBentErrors::SetPoint(i,0,0);
665 void TGraphBentErrors::SwapPoints(Int_t pos1, Int_t pos2)
667 SwapValues(fEXlow, pos1, pos2);
668 SwapValues(fEXhigh, pos1, pos2);
669 SwapValues(fEYlow, pos1, pos2);
670 SwapValues(fEYhigh, pos1, pos2);
672 SwapValues(fEXlowd, pos1, pos2);
673 SwapValues(fEXhighd, pos1, pos2);
674 SwapValues(fEYlowd, pos1, pos2);
675 SwapValues(fEYhighd, pos1, pos2);
677 TGraph::SwapPoints(pos1, pos2);