32 ClassImp(TGraphAsymmErrors);
 
   70 TGraphAsymmErrors::TGraphAsymmErrors(): TGraph()
 
   82 TGraphAsymmErrors::TGraphAsymmErrors(
const TGraphAsymmErrors &gr)
 
   85    if (!CtorAllocate()) 
return;
 
   86    Int_t n = fNpoints*
sizeof(Double_t);
 
   87    memcpy(fEXlow, gr.fEXlow, n);
 
   88    memcpy(fEYlow, gr.fEYlow, n);
 
   89    memcpy(fEXhigh, gr.fEXhigh, n);
 
   90    memcpy(fEYhigh, gr.fEYhigh, n);
 
   97 TGraphAsymmErrors& TGraphAsymmErrors::operator=(
const TGraphAsymmErrors &gr)
 
  100       TGraph::operator=(gr);
 
  102       if (fEXlow) 
delete [] fEXlow;
 
  103       if (fEYlow) 
delete [] fEYlow;
 
  104       if (fEXhigh) 
delete [] fEXhigh;
 
  105       if (fEYhigh) 
delete [] fEYhigh;
 
  107       if (!CtorAllocate()) 
return *
this;
 
  108       Int_t n = fNpoints*
sizeof(Double_t);
 
  109       memcpy(fEXlow, gr.fEXlow, n);
 
  110       memcpy(fEYlow, gr.fEYlow, n);
 
  111       memcpy(fEXhigh, gr.fEXhigh, n);
 
  112       memcpy(fEYhigh, gr.fEYhigh, n);
 
  123 TGraphAsymmErrors::TGraphAsymmErrors(Int_t n)
 
  126    if (!CtorAllocate()) 
return;
 
  127    FillZero(0, fNpoints);
 
  136 TGraphAsymmErrors::TGraphAsymmErrors(Int_t n, 
const Float_t *x, 
const Float_t *y, 
const Float_t *exl, 
const Float_t *exh, 
const Float_t *eyl, 
const Float_t *eyh)
 
  139    if (!CtorAllocate()) 
return;
 
  141    for (Int_t i=0;i<n;i++) {
 
  142       if (exl) fEXlow[i]  = exl[i];
 
  144       if (exh) fEXhigh[i] = exh[i];
 
  146       if (eyl) fEYlow[i]  = eyl[i];
 
  148       if (eyh) fEYhigh[i] = eyh[i];
 
  159 TGraphAsymmErrors::TGraphAsymmErrors(Int_t n, 
const Double_t *x, 
const Double_t *y, 
const Double_t *exl, 
const Double_t *exh, 
const Double_t *eyl, 
const Double_t *eyh)
 
  162    if (!CtorAllocate()) 
return;
 
  164    n = fNpoints*
sizeof(Double_t);
 
  165    if(exl) { memcpy(fEXlow, exl, n);
 
  166    } 
else { memset(fEXlow, 0, n); }
 
  167    if(exh) { memcpy(fEXhigh, exh, n);
 
  168    } 
else { memset(fEXhigh, 0, n); }
 
  169    if(eyl) { memcpy(fEYlow, eyl, n);
 
  170    } 
else { memset(fEYlow, 0, n); }
 
  171    if(eyh) { memcpy(fEYhigh, eyh, n);
 
  172    } 
else { memset(fEYhigh, 0, n); }
 
  183 TGraphAsymmErrors::TGraphAsymmErrors(
const TVectorF  &vx, 
const TVectorF  &vy, 
const TVectorF  &vexl, 
const TVectorF  &vexh, 
const TVectorF  &veyl, 
const TVectorF  &veyh)
 
  186    fNpoints = TMath::Min(vx.GetNrows(), vy.GetNrows());
 
  187    if (!TGraph::CtorAllocate()) 
return;
 
  188    if (!CtorAllocate()) 
return;
 
  189    Int_t ivxlow  = vx.GetLwb();
 
  190    Int_t ivylow  = vy.GetLwb();
 
  191    Int_t ivexllow = vexl.GetLwb();
 
  192    Int_t ivexhlow = vexh.GetLwb();
 
  193    Int_t iveyllow = veyl.GetLwb();
 
  194    Int_t iveyhlow = veyh.GetLwb();
 
  195       for (Int_t i=0;i<fNpoints;i++) {
 
  196       fX[i]      = vx(i+ivxlow);
 
  197       fY[i]      = vy(i+ivylow);
 
  198       fEXlow[i]  = vexl(i+ivexllow);
 
  199       fEYlow[i]  = veyl(i+iveyllow);
 
  200       fEXhigh[i] = vexh(i+ivexhlow);
 
  201       fEYhigh[i] = veyh(i+iveyhlow);
 
  213 TGraphAsymmErrors::TGraphAsymmErrors(
const TVectorD &vx, 
const TVectorD &vy, 
const TVectorD &vexl, 
const TVectorD &vexh, 
const TVectorD &veyl, 
const TVectorD &veyh)
 
  216    fNpoints = TMath::Min(vx.GetNrows(), vy.GetNrows());
 
  217    if (!TGraph::CtorAllocate()) 
return;
 
  218    if (!CtorAllocate()) 
return;
 
  219    Int_t ivxlow  = vx.GetLwb();
 
  220    Int_t ivylow  = vy.GetLwb();
 
  221    Int_t ivexllow = vexl.GetLwb();
 
  222    Int_t ivexhlow = vexh.GetLwb();
 
  223    Int_t iveyllow = veyl.GetLwb();
 
  224    Int_t iveyhlow = veyh.GetLwb();
 
  225       for (Int_t i=0;i<fNpoints;i++) {
 
  226       fX[i]      = vx(i+ivxlow);
 
  227       fY[i]      = vy(i+ivylow);
 
  228       fEXlow[i]  = vexl(i+ivexllow);
 
  229       fEYlow[i]  = veyl(i+iveyllow);
 
  230       fEXhigh[i] = vexh(i+ivexhlow);
 
  231       fEYhigh[i] = veyh(i+iveyhlow);
 
  240 TGraphAsymmErrors::TGraphAsymmErrors(
const TH1 *h)
 
  243    if (!CtorAllocate()) 
return;
 
  245    for (Int_t i=0;i<fNpoints;i++) {
 
  246       fEXlow[i]  = h->GetBinWidth(i+1)*gStyle->GetErrorX();
 
  247       fEXhigh[i] = fEXlow[i];
 
  248       fEYlow[i]  = h->GetBinErrorLow(i+1);
 
  249       fEYhigh[i] = h->GetBinErrorUp(i+1);;
 
  258 TGraphAsymmErrors::TGraphAsymmErrors(
const TH1* pass, 
const TH1* total, Option_t *option)
 
  259    : TGraph((pass)?pass->GetNbinsX():0)
 
  261    if (!pass || !total) {
 
  262       Error(
"TGraphAsymmErrors",
"Invalid histogram pointers");
 
  265    if (!CtorAllocate()) 
return;
 
  267    std::string sname = 
"divide_" + std::string(pass->GetName()) + 
"_by_" +
 
  268       std::string(total->GetName());
 
  269    SetName(sname.c_str());
 
  270    SetTitle(pass->GetTitle());
 
  273    pass->TAttLine::Copy(*
this);
 
  274    pass->TAttFill::Copy(*
this);
 
  275    pass->TAttMarker::Copy(*
this);
 
  277    Divide(pass, total, option);
 
  297 TGraphAsymmErrors::TGraphAsymmErrors(
const char *filename, 
const char *format, Option_t *option)
 
  300    if (!CtorAllocate()) 
return;
 
  301    Double_t x, y, exl, exh, eyl, eyh;
 
  302    TString fname = filename;
 
  303    gSystem->ExpandPathName(fname);
 
  304    std::ifstream infile(fname.Data());
 
  305    if (!infile.good()) {
 
  307       Error(
"TGraphErrors", 
"Cannot open file: %s, TGraphErrors is Zombie", filename);
 
  314    if (strcmp(option, 
"") == 0) { 
 
  316       Int_t ncol = TGraphErrors::CalculateScanfFields(format);  
 
  318       while (std::getline(infile, line, 
'\n')) {
 
  319          exl = exh = eyl = eyh = 0;
 
  321             res = sscanf(line.c_str(), format, &x, &y);
 
  322          } 
else if (ncol < 5) {
 
  323             res = sscanf(line.c_str(), format, &x, &y, &eyl, &eyh);
 
  325             res = sscanf(line.c_str(), format, &x, &y, &exl, &exh, &eyl, &eyh);
 
  331          SetPointError(np, exl, exh, eyl, eyh);
 
  339       TString format_ = TString(format) ;
 
  340       format_.ReplaceAll(
" ", 
"") ;
 
  341       format_.ReplaceAll(
"\t", 
"") ;
 
  342       format_.ReplaceAll(
"lg", 
"") ;
 
  343       format_.ReplaceAll(
"s", 
"") ;
 
  344       format_.ReplaceAll(
"%*", 
"0") ;
 
  345       format_.ReplaceAll(
"%", 
"1") ;
 
  346       if (!format_.IsDigit()) {
 
  347          Error(
"TGraphAsymmErrors", 
"Incorrect input format! Allowed format tags are {\"%%lg\",\"%%*lg\" or \"%%*s\"}");
 
  350       Int_t ntokens = format_.Length() ;
 
  352          Error(
"TGraphAsymmErrors", 
"Incorrect input format! Only %d tag(s) in format whereas at least 2 \"%%lg\" tags are expected!", ntokens);
 
  355       Int_t ntokensToBeSaved = 0 ;
 
  356       Bool_t * isTokenToBeSaved = 
new Bool_t [ntokens] ;
 
  357       for (Int_t idx = 0; idx < ntokens; idx++) {
 
  358          isTokenToBeSaved[idx] = TString::Format(
"%c", format_[idx]).Atoi() ; 
 
  359          if (isTokenToBeSaved[idx] == 1) {
 
  363       if (ntokens >= 2 && (ntokensToBeSaved < 2 || ntokensToBeSaved > 4)) { 
 
  364          Error(
"TGraphAsymmErrors", 
"Incorrect input format! There are %d \"%%lg\" tag(s) in format whereas 2,3 or 4 are expected!", ntokensToBeSaved);
 
  365          delete [] isTokenToBeSaved ;
 
  370       Bool_t isLineToBeSkipped = kFALSE ; 
 
  371       char * token = NULL ;
 
  372       TString token_str = 
"" ;
 
  373       Int_t token_idx = 0 ;
 
  374       Double_t * value = 
new Double_t [6] ; 
 
  375       for (Int_t k = 0; k < 6; k++) {
 
  378       Int_t value_idx = 0 ;
 
  382       while (std::getline(infile, line, 
'\n')) {
 
  384             if (line[line.size() - 1] == char(13)) {  
 
  385                line.erase(line.end() - 1, line.end()) ;
 
  387             token = R__STRTOK_R(const_cast<char*>(line.c_str()), option, &rest) ;
 
  388             while (token != NULL && value_idx < ntokensToBeSaved) {
 
  389                if (isTokenToBeSaved[token_idx]) {
 
  390                   token_str = TString(token) ;
 
  391                   token_str.ReplaceAll(
"\t", 
"") ;
 
  392                   if (!token_str.IsFloat()) {
 
  393                      isLineToBeSkipped = kTRUE ;
 
  396                      value[value_idx] = token_str.Atof() ;
 
  400                token = R__STRTOK_R(NULL, option, &rest); 
 
  403             if (!isLineToBeSkipped && value_idx > 1) { 
 
  411                SetPointError(np, exl, exh, eyl, eyh);
 
  415          isLineToBeSkipped = kFALSE ;
 
  423       delete [] isTokenToBeSaved ;
 
  433 TGraphAsymmErrors::~TGraphAsymmErrors()
 
  435    if(fEXlow) 
delete [] fEXlow;
 
  436    if(fEXhigh) 
delete [] fEXhigh;
 
  437    if(fEYlow) 
delete [] fEYlow;
 
  438    if(fEYhigh) 
delete [] fEYhigh;
 
  444 Double_t** TGraphAsymmErrors::Allocate(Int_t size) {
 
  445    return AllocateArrays(6, size);
 
  458 void TGraphAsymmErrors::Apply(TF1 *f)
 
  460    Double_t x,y,exl,exh,eyl,eyh,eyl_new,eyh_new,fxy;
 
  466    for (Int_t i=0;i<GetN();i++) {
 
  469       exh=GetErrorXhigh(i);
 
  471       eyh=GetErrorYhigh(i);
 
  478       if (f->Eval(x,y-eyl)<f->Eval(x,y+eyh)) {
 
  479          eyl_new = TMath::Abs(fxy - f->Eval(x,y-eyl));
 
  480          eyh_new = TMath::Abs(f->Eval(x,y+eyh) - fxy);
 
  483          eyh_new = TMath::Abs(fxy - f->Eval(x,y-eyl));
 
  484          eyl_new = TMath::Abs(f->Eval(x,y+eyh) - fxy);
 
  488       SetPointError(i,exl,exh,eyl_new,eyh_new);
 
  490    if (gPad) gPad->Modified();
 
  499 void TGraphAsymmErrors::BayesDivide(
const TH1* pass, 
const TH1* total, Option_t *)
 
  501    Divide(pass,total,
"cl=0.683 b(1,1) mode");
 
  579 void TGraphAsymmErrors::Divide(
const TH1* pass, 
const TH1* total, Option_t *opt)
 
  582    if(!pass || !total) {
 
  583       Error(
"Divide",
"one of the passed pointers is zero");
 
  588    if((pass->GetDimension() > 1) || (total->GetDimension() > 1)) {
 
  589       Error(
"Divide",
"passed histograms are not one-dimensional");
 
  595    Bool_t bEffective = 
false;
 
  600    if (pass->GetSumw2()->fN > 0) {
 
  601       for (
int i = 0; i < pass->GetNcells(); ++i) {
 
  602          psumw += pass->GetBinContent(i);
 
  603          psumw2 += pass->GetSumw2()->At(i);
 
  607       psumw = pass->GetSumOfWeights();
 
  610    if (TMath::Abs(psumw - psumw2) > 1e-6)
 
  615    if (total->GetSumw2()->fN > 0) {
 
  616       for (
int i = 0; i < total->GetNcells(); ++i) {
 
  617          tsumw += total->GetBinContent(i);
 
  618          tsumw2 += total->GetSumw2()->At(i);
 
  622       tsumw = total->GetSumOfWeights();
 
  625    if (TMath::Abs(tsumw - tsumw2) > 1e-6)
 
  637    TString option = opt;
 
  640    Bool_t bVerbose = 
false;
 
  643    Double_t (*pBound)(Double_t,Double_t,Double_t,Bool_t) = &TEfficiency::ClopperPearson; 
 
  645    Double_t conf = 0.682689492137;
 
  647    Bool_t bIsBayesian = 
false;
 
  652    if(option.Contains(
"v")) {
 
  653       option.ReplaceAll(
"v",
"");
 
  656          Info(
"Divide",
"weight will be considered in the Histogram Ratio");
 
  661    if(option.Contains(
"cl=")) {
 
  664       sscanf(strstr(option.Data(),
"cl="),
"cl=%lf",&level);
 
  665       if((level > 0) && (level < 1))
 
  668          Warning(
"Divide",
"given confidence level %.3lf is invalid",level);
 
  669       option.ReplaceAll(
"cl=",
"");
 
  675    Bool_t usePosteriorMode = 
false;
 
  676    Bool_t useShortestInterval = 
false;
 
  677    if (option.Contains(
"b(")) {
 
  680       sscanf(strstr(option.Data(), 
"b("), 
"b(%lf,%lf)", &a, &b);
 
  684          Warning(
"Divide", 
"given shape parameter for alpha %.2lf is invalid", a);
 
  688          Warning(
"Divide", 
"given shape parameter for beta %.2lf is invalid", b);
 
  689       option.ReplaceAll(
"b(", 
"");
 
  696       if (option.Contains(
"mode")) {
 
  697          usePosteriorMode = 
true;
 
  698          option.ReplaceAll(
"mode", 
"");
 
  700       if (option.Contains(
"sh") || (usePosteriorMode && !option.Contains(
"cen"))) {
 
  701          useShortestInterval = 
true;
 
  705    else if (option.Contains(
"n")) {
 
  706       option.ReplaceAll(
"n", 
"");
 
  707       pBound = &TEfficiency::Normal;
 
  710    else if (option.Contains(
"cp")) {
 
  711       option.ReplaceAll(
"cp", 
"");
 
  712       pBound = &TEfficiency::ClopperPearson;
 
  715    else if (option.Contains(
"w")) {
 
  716       option.ReplaceAll(
"w", 
"");
 
  717       pBound = &TEfficiency::Wilson;
 
  720    else if (option.Contains(
"ac")) {
 
  721       option.ReplaceAll(
"ac", 
"");
 
  722       pBound = &TEfficiency::AgrestiCoull;
 
  725    else if (option.Contains(
"fc")) {
 
  726       option.ReplaceAll(
"fc", 
"");
 
  727       pBound = &TEfficiency::FeldmanCousins;
 
  730    else if (option.Contains(
"midp")) {
 
  731       option.ReplaceAll(
"midp", 
"");
 
  732       pBound = &TEfficiency::MidPInterval;
 
  736    Bool_t bPoissonRatio = 
false;
 
  737    if (option.Contains(
"pois")) {
 
  738       bPoissonRatio = 
true;
 
  739       option.ReplaceAll(
"pois", 
"");
 
  741    Bool_t plot0Bins = 
false;
 
  742    if (option.Contains(
"e0")) {
 
  744       option.ReplaceAll(
"e0", 
"");
 
  749    if ((bEffective && !bPoissonRatio) && !bIsBayesian && pBound != &TEfficiency::Normal) {
 
  750       Warning(
"Divide", 
"Histograms have weights: only Normal or Bayesian error calculation is supported");
 
  751       Info(
"Divide", 
"Using now the Normal approximation for weighted histograms");
 
  755       if (pass->GetDimension() != total->GetDimension()) {
 
  756          Error(
"Divide", 
"passed histograms are not of the same dimension");
 
  760       if (!TEfficiency::CheckBinning(*pass, *total)) {
 
  761          Error(
"Divide", 
"passed histograms are not consistent");
 
  766       if (!TEfficiency::CheckConsistency(*pass, *total, 
"w")) {
 
  767          Error(
"Divide", 
"passed histograms are not consistent");
 
  774    Int_t nbins = pass->GetNbinsX();
 
  782    double eff, low, upper;
 
  786    Double_t t = 0 , p = 0;
 
  787    Double_t tw = 0, tw2 = 0, pw = 0, pw2 = 0, wratio = 1; 
 
  789    for (Int_t b=1; b<=nbins; ++b) {
 
  798          tw = total->GetBinContent(b);
 
  799          tw2 = (total->GetSumw2()->fN > 0) ? total->GetSumw2()->At(b) : tw;
 
  800          pw = pass->GetBinContent(b);
 
  801          pw2 = (pass->GetSumw2()->fN > 0) ? pass->GetSumw2()->At(b) : pw;
 
  809             if (pw == 0 && pw2 == 0)
 
  814             if (tw == 0 && tw2 == 0)
 
  819             if (pw > 0 && tw > 0)
 
  821                wratio = (pw * t) / (p * tw);
 
  822             else if (pw == 0 && tw > 0)
 
  825                wratio = (psumw2 * t) / (psumw * tw);
 
  826             else if (tw == 0 && pw > 0)
 
  829                wratio = (pw * tsumw) / (p * tsumw2);
 
  834                if (!plot0Bins) 
continue; 
 
  839          } 
else if (tw <= 0 && !plot0Bins)
 
  849          t = std::round(total->GetBinContent(b));
 
  850          p = std::round(pass->GetBinContent(b));
 
  855          if (t == 0.0 && !plot0Bins)
 
  863          if ((bEffective && !bPoissonRatio) && tw2 <= 0) {
 
  866             low = eff; upper = eff;
 
  870             if (bEffective && !bPoissonRatio) {
 
  872                double norm = tw/tw2;  
 
  873                aa =  pw * norm + alpha;
 
  874                bb =  (tw - pw) * norm + beta;
 
  877                aa = double(p) + alpha;
 
  878                bb = double(t-p) + beta;
 
  880             if (usePosteriorMode)
 
  881                eff = TEfficiency::BetaMode(aa,bb);
 
  883                eff = TEfficiency::BetaMean(aa,bb);
 
  885             if (useShortestInterval) {
 
  886                TEfficiency::BetaShortestInterval(conf,aa,bb,low,upper);
 
  889                low = TEfficiency::BetaCentralInterval(conf,aa,bb,
false);
 
  890                upper = TEfficiency::BetaCentralInterval(conf,aa,bb,
true);
 
  896          if (bEffective && !bPoissonRatio) {
 
  905                double variance = ( pw2 * (1. - 2 * eff) + tw2 * eff *eff ) / ( tw * tw) ;
 
  906                double sigma = sqrt(variance);
 
  908                double prob = 0.5 * (1.-conf);
 
  909                double delta = ROOT::Math::normal_quantile_c(prob, sigma);
 
  912                if (low < 0) low = 0;
 
  913                if (upper > 1) upper = 1.;
 
  919                eff = ((Double_t)p)/t;
 
  921             low = pBound(t,p,conf,
false);
 
  922             upper = pBound(t,p,conf,
true);
 
  928         Double_t ratio = eff/(1 - eff);
 
  930         low = low/(1. - low);
 
  931         upper = upper/(1.-upper);
 
  941       if (TMath::Finite(eff)) {
 
  942          SetPoint(npoint,pass->GetBinCenter(b),eff);
 
  943          SetPointError(npoint,
 
  944          pass->GetBinCenter(b)-pass->GetBinLowEdge(b),
 
  945          pass->GetBinLowEdge(b)-pass->GetBinCenter(b)+pass->GetBinWidth(b),
 
  953       Warning(
"Divide",
"Number of graph points is different than histogram bins - %d points have been skipped",nbins-npoint);
 
  957       Info(
"Divide",
"made a graph with %d points from %d bins",npoint,nbins);
 
  958       Info(
"Divide",
"used confidence level: %.2lf\n",conf);
 
  960          Info(
"Divide",
"used prior probability ~ beta(%.2lf,%.2lf)",alpha,beta);
 
  968 void TGraphAsymmErrors::ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax)
 const 
  970    TGraph::ComputeRange(xmin,ymin,xmax,ymax);
 
  972    for (Int_t i=0;i<fNpoints;i++) {
 
  973       if (fX[i] -fEXlow[i] < xmin) {
 
  974          if (gPad && gPad->GetLogx()) {
 
  975             if (fEXlow[i] < fX[i]) xmin = fX[i]-fEXlow[i];
 
  976             else                   xmin = TMath::Min(xmin,fX[i]/3);
 
  978             xmin = fX[i]-fEXlow[i];
 
  981       if (fX[i] +fEXhigh[i] > xmax) xmax = fX[i]+fEXhigh[i];
 
  982       if (fY[i] -fEYlow[i] < ymin) {
 
  983          if (gPad && gPad->GetLogy()) {
 
  984             if (fEYlow[i] < fY[i]) ymin = fY[i]-fEYlow[i];
 
  985             else                   ymin = TMath::Min(ymin,fY[i]/3);
 
  987             ymin = fY[i]-fEYlow[i];
 
  990       if (fY[i] +fEYhigh[i] > ymax) ymax = fY[i]+fEYhigh[i];
 
  998 void TGraphAsymmErrors::CopyAndRelease(Double_t **newarrays,
 
  999                                        Int_t ibegin, Int_t iend, Int_t obegin)
 
 1001    CopyPoints(newarrays, ibegin, iend, obegin);
 
 1004       fEXlow = newarrays[0];
 
 1006       fEXhigh = newarrays[1];
 
 1008       fEYlow = newarrays[2];
 
 1010       fEYhigh = newarrays[3];
 
 1024 Bool_t TGraphAsymmErrors::CopyPoints(Double_t **arrays,
 
 1025                                      Int_t ibegin, Int_t iend, Int_t obegin)
 
 1027    if (TGraph::CopyPoints(arrays ? arrays+4 : 0, ibegin, iend, obegin)) {
 
 1028       Int_t n = (iend - ibegin)*
sizeof(Double_t);
 
 1030          memmove(&arrays[0][obegin], &fEXlow[ibegin], n);
 
 1031          memmove(&arrays[1][obegin], &fEXhigh[ibegin], n);
 
 1032          memmove(&arrays[2][obegin], &fEYlow[ibegin], n);
 
 1033          memmove(&arrays[3][obegin], &fEYhigh[ibegin], n);
 
 1035          memmove(&fEXlow[obegin], &fEXlow[ibegin], n);
 
 1036          memmove(&fEXhigh[obegin], &fEXhigh[ibegin], n);
 
 1037          memmove(&fEYlow[obegin], &fEYlow[ibegin], n);
 
 1038          memmove(&fEYhigh[obegin], &fEYhigh[ibegin], n);
 
 1052 Bool_t TGraphAsymmErrors::CtorAllocate(
void)
 
 1055       fEXlow = fEYlow = fEXhigh = fEYhigh = 0;
 
 1058    fEXlow = 
new Double_t[fMaxSize];
 
 1059    fEYlow = 
new Double_t[fMaxSize];
 
 1060    fEXhigh = 
new Double_t[fMaxSize];
 
 1061    fEYhigh = 
new Double_t[fMaxSize];
 
 1068 Bool_t TGraphAsymmErrors::DoMerge(
const TGraph *g)
 
 1070    if (g->GetN() == 0) 
return kFALSE;
 
 1072    Double_t * exl = g->GetEXlow();
 
 1073    Double_t * exh = g->GetEXhigh();
 
 1074    Double_t * eyl = g->GetEYlow();
 
 1075    Double_t * eyh = g->GetEYhigh();
 
 1076    if (exl == 0 || exh == 0 || eyl == 0 || eyh == 0) {
 
 1077       if (g->IsA() != TGraph::Class() )
 
 1078          Warning(
"DoMerge",
"Merging a %s is not compatible with a TGraphAsymmErrors - errors will be ignored",g->IsA()->GetName());
 
 1079       return TGraph::DoMerge(g);
 
 1081    for (Int_t i = 0 ; i < g->GetN(); i++) {
 
 1082       Int_t ipoint = GetN();
 
 1083       Double_t x = g->GetX()[i];
 
 1084       Double_t y = g->GetY()[i];
 
 1085       SetPoint(ipoint, x, y);
 
 1086       SetPointError(ipoint, exl[i], exh[i], eyl[i], eyh[i] );
 
 1095 void TGraphAsymmErrors::FillZero(Int_t begin, Int_t end,
 
 1099       TGraph::FillZero(begin, end, from_ctor);
 
 1101    Int_t n = (end - begin)*
sizeof(Double_t);
 
 1102    memset(fEXlow + begin, 0, n);
 
 1103    memset(fEXhigh + begin, 0, n);
 
 1104    memset(fEYlow + begin, 0, n);
 
 1105    memset(fEYhigh + begin, 0, n);
 
 1113 Double_t TGraphAsymmErrors::GetErrorX(Int_t i)
 const 
 1115    if (i < 0 || i >= fNpoints) 
return -1;
 
 1116    if (!fEXlow && !fEXhigh) 
return -1;
 
 1117    Double_t elow=0, ehigh=0;
 
 1118    if (fEXlow)  elow  = fEXlow[i];
 
 1119    if (fEXhigh) ehigh = fEXhigh[i];
 
 1120    return TMath::Sqrt(0.5*(elow*elow + ehigh*ehigh));
 
 1128 Double_t TGraphAsymmErrors::GetErrorY(Int_t i)
 const 
 1130    if (i < 0 || i >= fNpoints) 
return -1;
 
 1131    if (!fEYlow && !fEYhigh) 
return -1;
 
 1132    Double_t elow=0, ehigh=0;
 
 1133    if (fEYlow)  elow  = fEYlow[i];
 
 1134    if (fEYhigh) ehigh = fEYhigh[i];
 
 1135    return TMath::Sqrt(0.5*(elow*elow + ehigh*ehigh));
 
 1142 Double_t TGraphAsymmErrors::GetErrorXhigh(Int_t i)
 const 
 1144    if (i<0 || i>fNpoints) 
return -1;
 
 1145    if (fEXhigh) 
return fEXhigh[i];
 
 1153 Double_t TGraphAsymmErrors::GetErrorXlow(Int_t i)
 const 
 1155    if (i<0 || i>fNpoints) 
return -1;
 
 1156    if (fEXlow) 
return fEXlow[i];
 
 1164 Double_t TGraphAsymmErrors::GetErrorYhigh(Int_t i)
 const 
 1166    if (i<0 || i>fNpoints) 
return -1;
 
 1167    if (fEYhigh) 
return fEYhigh[i];
 
 1175 Double_t TGraphAsymmErrors::GetErrorYlow(Int_t i)
 const 
 1177    if (i<0 || i>fNpoints) 
return -1;
 
 1178    if (fEYlow) 
return fEYlow[i];
 
 1187 Int_t TGraphAsymmErrors::Merge(TCollection* li)
 
 1190    while (TObject* o = next()) {
 
 1191       TGraph *g = 
dynamic_cast<TGraph*
>(o);
 
 1194                "Cannot merge - an object which doesn't inherit from TGraph found in the list");
 
 1198       int n1 = n0+g->GetN();
 
 1200       Double_t * x = g->GetX();
 
 1201       Double_t * y = g->GetY();
 
 1202       Double_t * exlow  = g->GetEXlow();
 
 1203       Double_t * exhigh = g->GetEXhigh();
 
 1204       Double_t * eylow  = g->GetEYlow();
 
 1205       Double_t * eyhigh = g->GetEYhigh();
 
 1206       for (Int_t i = 0 ; i < g->GetN(); i++) {
 
 1207          SetPoint(n0+i, x[i], y[i]);
 
 1208          if (exlow)  fEXlow[n0+i]  = exlow[i];
 
 1209          if (exhigh) fEXhigh[n0+i] = exhigh[i];
 
 1210          if (eylow)  fEYlow[n0+i]  = eylow[i];
 
 1211          if (eyhigh) fEYhigh[n0+i] = eyhigh[i];
 
 1220 void TGraphAsymmErrors::Print(Option_t *)
 const 
 1222    for (Int_t i=0;i<fNpoints;i++) {
 
 1223       printf(
"x[%d]=%g, y[%d]=%g, exl[%d]=%g, exh[%d]=%g, eyl[%d]=%g, eyh[%d]=%g\n" 
 1224          ,i,fX[i],i,fY[i],i,fEXlow[i],i,fEXhigh[i],i,fEYlow[i],i,fEYhigh[i]);
 
 1232 void TGraphAsymmErrors::SavePrimitive(std::ostream &out, Option_t *option )
 
 1235    out << 
"   " << std::endl;
 
 1236    static Int_t frameNumber = 3000;
 
 1240    TString fXName   = TString(GetName()) + Form(
"_fx%d",frameNumber);
 
 1241    TString fYName   = TString(GetName()) + Form(
"_fy%d",frameNumber);
 
 1242    TString fElXName = TString(GetName()) + Form(
"_felx%d",frameNumber);
 
 1243    TString fElYName = TString(GetName()) + Form(
"_fely%d",frameNumber);
 
 1244    TString fEhXName = TString(GetName()) + Form(
"_fehx%d",frameNumber);
 
 1245    TString fEhYName = TString(GetName()) + Form(
"_fehy%d",frameNumber);
 
 1246    out << 
"   Double_t " << fXName << 
"[" << fNpoints << 
"] = {" << std::endl;
 
 1247    for (i = 0; i < fNpoints-1; i++) out << 
"   " << fX[i] << 
"," << std::endl;
 
 1248    out << 
"   " << fX[fNpoints-1] << 
"};" << std::endl;
 
 1249    out << 
"   Double_t " << fYName << 
"[" << fNpoints << 
"] = {" << std::endl;
 
 1250    for (i = 0; i < fNpoints-1; i++) out << 
"   " << fY[i] << 
"," << std::endl;
 
 1251    out << 
"   " << fY[fNpoints-1] << 
"};" << std::endl;
 
 1252    out << 
"   Double_t " << fElXName << 
"[" << fNpoints << 
"] = {" << std::endl;
 
 1253    for (i = 0; i < fNpoints-1; i++) out << 
"   " << fEXlow[i] << 
"," << std::endl;
 
 1254    out << 
"   " << fEXlow[fNpoints-1] << 
"};" << std::endl;
 
 1255    out << 
"   Double_t " << fElYName << 
"[" << fNpoints << 
"] = {" << std::endl;
 
 1256    for (i = 0; i < fNpoints-1; i++) out << 
"   " << fEYlow[i] << 
"," << std::endl;
 
 1257    out << 
"   " << fEYlow[fNpoints-1] << 
"};" << std::endl;
 
 1258    out << 
"   Double_t " << fEhXName << 
"[" << fNpoints << 
"] = {" << std::endl;
 
 1259    for (i = 0; i < fNpoints-1; i++) out << 
"   " << fEXhigh[i] << 
"," << std::endl;
 
 1260    out << 
"   " << fEXhigh[fNpoints-1] << 
"};" << std::endl;
 
 1261    out << 
"   Double_t " << fEhYName << 
"[" << fNpoints << 
"] = {" << std::endl;
 
 1262    for (i = 0; i < fNpoints-1; i++) out << 
"   " << fEYhigh[i] << 
"," << std::endl;
 
 1263    out << 
"   " << fEYhigh[fNpoints-1] << 
"};" << std::endl;
 
 1265    if (gROOT->ClassSaved(TGraphAsymmErrors::Class())) out<<
"   ";
 
 1266    else out << 
"   TGraphAsymmErrors *";
 
 1267    out << 
"grae = new TGraphAsymmErrors("<< fNpoints << 
"," 
 1268                                     << fXName   << 
","  << fYName  << 
"," 
 1269                                     << fElXName  << 
","  << fEhXName << 
"," 
 1270                                     << fElYName  << 
","  << fEhYName << 
");" 
 1273    out << 
"   grae->SetName(" << quote << GetName() << quote << 
");" << std::endl;
 
 1274    out << 
"   grae->SetTitle(" << quote << GetTitle() << quote << 
");" << std::endl;
 
 1276    SaveFillAttributes(out, 
"grae", 0, 1001);
 
 1277    SaveLineAttributes(out, 
"grae", 1, 1, 1);
 
 1278    SaveMarkerAttributes(out, 
"grae", 1, 1, 1);
 
 1281       TString hname = fHistogram->GetName();
 
 1282       hname += frameNumber;
 
 1283       fHistogram->SetName(Form(
"Graph_%s",hname.Data()));
 
 1284       fHistogram->SavePrimitive(out,
"nodraw");
 
 1285       out<<
"   grae->SetHistogram("<<fHistogram->GetName()<<
");"<<std::endl;
 
 1286       out<<
"   "<<std::endl;
 
 1290    TIter next(fFunctions);
 
 1292    while ((obj = next())) {
 
 1293       obj->SavePrimitive(out, Form(
"nodraw #%d\n",++frameNumber));
 
 1294       if (obj->InheritsFrom(
"TPaveStats")) {
 
 1295          out << 
"   grae->GetListOfFunctions()->Add(ptstats);" << std::endl;
 
 1296          out << 
"   ptstats->SetParent(grae->GetListOfFunctions());" << std::endl;
 
 1299          objname.Form(
"%s%d",obj->GetName(),frameNumber);
 
 1300          if (obj->InheritsFrom(
"TF1")) {
 
 1301             out << 
"   " << objname << 
"->SetParent(grae);\n";
 
 1303          out << 
"   grae->GetListOfFunctions()->Add(" 
 1304              << objname << 
");" << std::endl;
 
 1308    const char *l = strstr(option,
"multigraph");
 
 1310       out<<
"   multigraph->Add(grae,"<<quote<<l+10<<quote<<
");"<<std::endl;
 
 1312       out<<
"   grae->Draw("<<quote<<option<<quote<<
");"<<std::endl;
 
 1319 void TGraphAsymmErrors::SetPointError(Double_t exl, Double_t exh, Double_t eyl, Double_t eyh)
 
 1321    Int_t px = gPad->GetEventX();
 
 1322    Int_t py = gPad->GetEventY();
 
 1328    for (i=0;i<fNpoints;i++) {
 
 1329       Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
 
 1330       Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
 
 1331       if (dpx*dpx+dpy*dpy < 25) {ipoint = i; 
break;}
 
 1333    if (ipoint == -2) 
return;
 
 1335    fEXlow[ipoint]  = exl;
 
 1336    fEYlow[ipoint]  = eyl;
 
 1337    fEXhigh[ipoint] = exh;
 
 1338    fEYhigh[ipoint] = eyh;
 
 1346 void TGraphAsymmErrors::SetPointError(Int_t i, Double_t exl, Double_t exh, Double_t eyl, Double_t eyh)
 
 1349    if (i >= fNpoints) {
 
 1351       TGraphAsymmErrors::SetPoint(i,0,0);
 
 1363 void TGraphAsymmErrors::SetPointEXlow(Int_t i, Double_t exl)
 
 1366    if (i >= fNpoints) {
 
 1368       TGraphAsymmErrors::SetPoint(i,0,0);
 
 1377 void TGraphAsymmErrors::SetPointEXhigh(Int_t i, Double_t exh)
 
 1380    if (i >= fNpoints) {
 
 1382       TGraphAsymmErrors::SetPoint(i,0,0);
 
 1391 void TGraphAsymmErrors::SetPointEYlow(Int_t i, Double_t eyl)
 
 1394    if (i >= fNpoints) {
 
 1396       TGraphAsymmErrors::SetPoint(i,0,0);
 
 1405 void TGraphAsymmErrors::SetPointEYhigh(Int_t i, Double_t eyh)
 
 1408    if (i >= fNpoints) {
 
 1410       TGraphAsymmErrors::SetPoint(i,0,0);
 
 1419 void TGraphAsymmErrors::Streamer(TBuffer &b)
 
 1421    if (b.IsReading()) {
 
 1423       Version_t R__v = b.ReadVersion(&R__s, &R__c);
 
 1425          b.ReadClassBuffer(TGraphAsymmErrors::Class(), 
this, R__v, R__s, R__c);
 
 1429       TGraph::Streamer(b);
 
 1430       fEXlow  = 
new Double_t[fNpoints];
 
 1431       fEYlow  = 
new Double_t[fNpoints];
 
 1432       fEXhigh = 
new Double_t[fNpoints];
 
 1433       fEYhigh = 
new Double_t[fNpoints];
 
 1435          Float_t *exlow  = 
new Float_t[fNpoints];
 
 1436          Float_t *eylow  = 
new Float_t[fNpoints];
 
 1437          Float_t *exhigh = 
new Float_t[fNpoints];
 
 1438          Float_t *eyhigh = 
new Float_t[fNpoints];
 
 1439          b.ReadFastArray(exlow,fNpoints);
 
 1440          b.ReadFastArray(eylow,fNpoints);
 
 1441          b.ReadFastArray(exhigh,fNpoints);
 
 1442          b.ReadFastArray(eyhigh,fNpoints);
 
 1443          for (Int_t i=0;i<fNpoints;i++) {
 
 1444             fEXlow[i]  = exlow[i];
 
 1445             fEYlow[i]  = eylow[i];
 
 1446             fEXhigh[i] = exhigh[i];
 
 1447             fEYhigh[i] = eyhigh[i];
 
 1454          b.ReadFastArray(fEXlow,fNpoints);
 
 1455          b.ReadFastArray(fEYlow,fNpoints);
 
 1456          b.ReadFastArray(fEXhigh,fNpoints);
 
 1457          b.ReadFastArray(fEYhigh,fNpoints);
 
 1459       b.CheckByteCount(R__s, R__c, TGraphAsymmErrors::IsA());
 
 1463       b.WriteClassBuffer(TGraphAsymmErrors::Class(),
this);
 
 1471 void TGraphAsymmErrors::SwapPoints(Int_t pos1, Int_t pos2)
 
 1473    SwapValues(fEXlow,  pos1, pos2);
 
 1474    SwapValues(fEXhigh, pos1, pos2);
 
 1475    SwapValues(fEYlow,  pos1, pos2);
 
 1476    SwapValues(fEYhigh, pos1, pos2);
 
 1477    TGraph::SwapPoints(pos1, pos2);