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);