TGraphAsymmErrors error with constructor from file

I am trying to read in data from a standard csv file into a TGraphAsymmErrors. However I get an errors stating that only 2, 3, or 4 arguments are expected, not 6.

Looking through the underlying ROOT code, it appears this check is only done when a delimiter (in this case โ€œ,โ€) is specified, and the code appears to be copied verbatim from TGraphErrors.h without updating the expected number of arguments to 6 for asymmetric errors.

I have confirmed that the constructor works and reads in all 6 values if I use a file with a single space as delimiter, and do not pass a delimiter to the constructor.

A minimal working example and resulting error message are given below.

#include <iostream>
#include "TGraphAsymmErrors.h"

void tgraphasymmetricerrors_test()
{
    //CSV format should be X,Y,XEL,XEH,YEL,YEH. Other columns should be skipped with %*lg
    string filename = "test_data.txt";
    TGraphAsymmErrors* data_graph = new TGraphAsymmErrors(filename.c_str(), "%lg %lg %lg %lg %lg %lg", ",");
    if (!data_graph)
    {
	std::cout<<"Could not open TGraphAsymmErrors: "<<filename<<std::endl;
	return;
    }
}

Error in TGraphAsymmErrors::TGraphAsymmErrors: Incorrect input format! There are 6 โ€œ%lgโ€ tag(s) in format whereas 2,3 or 4 are expected!

test_data.txt (39 Bytes)


_ROOT Version: 6.32.08
_Platform: macOS Sonoma 14.7.4


Welcome to the ROOT forum,

I agree it is weird because according to the documentaion you specified the default format ! so it should not complain.
If you do:

    TGraphAsymmErrors* data_graph = new TGraphAsymmErrors(filename.c_str());

it is ok.
I think a fix is needed there.

The problem comes from the fact you are using a delimiter. If in your example you use:

    TGraphAsymmErrors* data_graph = new TGraphAsymmErrors(filename.c_str(), "%lg %lg %lg %lg %lg %lg");

ie: no delimiter
and replace all the "," by " " in your data file then it works.
That should be fix. I am looking at it.

Probably on/around these lines (365-369) in TGraphAsymmErrors.cxx:

      if (ntokens >= 2 && (ntokensToBeSaved < 2 || ntokensToBeSaved > 4)) { //first condition not to repeat the previous error message
         Error("TGraphAsymmErrors", "Incorrect input format! There are %d \"%%lg\" tag(s) in format whereas 2,3 or 4 are expected!", ntokensToBeSaved);
         delete [] isTokenToBeSaved;
         return ;
      }

I think the if should check whether ntokensToBeSaved is โ€œnot 2, 4 or 6โ€, instead of checking for โ€œ<2 or >4โ€ (which is for TGraphErrors, as the original post mentioned).

This PR fixes the problem:

Thank you for the quick responses and fix!

While you are making changes, could you also fix the documentation for this constructor:

Current documentation:

format = "%lg %lg %lg %lg %lg %lg" read only 6 first columns into X, Y, EXL, EYH, EYL, EHY

Suggested change

format = "%lg %lg %lg %lg %lg %lg" read only 6 first columns into X, Y, EXL, EXH, EYL, EYH

(errors in x should go first, and switch to a consistent ordering for the notation)

indeed more changes are required. I am on it

done: [skip-ci] fix doc typos. by couet ยท Pull Request #17997 ยท root-project/root ยท GitHub
Thanks to have seen it.

1 Like