Read ASCII file with nan value

Hi,
I failed to read an ASCII file with nan value into a tree. After searching the forum and internet, I did not find a solution to it. Since I am new user of ROOT, I appreciate your comments.

My fake data file(testdata.dat) is as follows:
1,2
3,4
nan,6

and my code (treetest.C)is

void treetest()
{
gROOT->Reset();
TTree* pMytree = new TTree(“SimpleTree”,“An example of tree”);

//Long64_t nlines = pMytree->ReadFile(“testdata.dat”,“x:y”);
//printf(“found %lld points\n”,nlines);

ifstream in(“testdata.dat”);

float x,y;

pMytree->Branch(“x”,&x,“x/F”);
pMytree->Branch(“y”,&y,“y/F”);

while(!in.eof()){
in>>x>>y;

pMytree->Fill();

}

//pMytree->Show(1);
//pMytree->Draw(“x”,“y”);
pMytree->Print();
//pMytree->Write();

}

When I use pMytree->ReadFile(“testdata.dat”,“x:y”) to read the data, it only reads the first two rows and did not read the row with nan value.

For the loop method, it frozend. Any suggestions? Thank you very much.

regards,

Gang Ma

Hi,in >> x;will fail when seeing something that is not a double. and set the stream in an ‘invalid state’. Once the stream is in an invalid state, it will no longer read anything (aka operator is a no-op). [Note that ‘nan’ is not considered a valid float by ifstream).
So to support this notation, you will need to read the data as a string and parse it afterhand.

Cheers,
Philippe

Hi,Philippe,
Thank for your answer. I changed my program to parse the NaN string into float. It is still not working because of the numeric_limits stuff.

Here are the details:
To simplify the matter, I use the following data(test.dat)
1
2
nan

My program is
bool string2double(char* digit, double& result) {
int sign = 1;

result = 0;

// check sign
if (*digit == ‘-’) {
sign = -1;
digit++;
}

//— get integer portion
while (*digit >= ‘0’ && *digit <=‘9’) {
result = (result * 10) + *digit-‘0’;
digit++;
}

//— get decimal point and fraction, if any.
if (*digit == ‘.’) {
digit++;
double scale = 0.1;
while (*digit >= ‘0’ && *digit <=‘9’) {
result += (*digit-‘0’) * scale;
scale *= 0.1;
digit++;
}
}

//— error if we’re not at the end of the number
if (*digit != 0) {
return false;
}

//— set to sign given at the front
result = result * sign;
return true;
}

void treetest()
{

gROOT->Reset();
TTree* pMytree = new TTree(“SimpleTree”,“An example of tree”);

//Long64_t nlines = pMytree->ReadFile(“testdata.dat”,“x:y”);
//printf(“found %lld points\n”,nlines);

ifstream in(“test.dat”);

if(!in)
cout<<“Cann’t open file”<<endl;

cout<<“Here is OK”<<endl;

string s;
double f=0.0;

// float x,y;

float x;
pMytree->Branch(“x”,&x,“x/F”);
// pMytree->Branch(“y”,&y,“y/F”);

while(!in.eof()){
// in>>x>>y;
getline(in,s);
//if(from_string(f,s,std::dec))
//if(EOF==strtod(s,NULL))
if (string2double(s.c_str(),f))
x=f;
else
x=std::numeric_limits::quiet_NaN();

pMytree->Fill();

}

// pMytree->Fill();

// pMytree->Show(1);
pMytree->Draw(“x”);
pMytree->Print();
//pMytree->Write();

}

The error messages are as follows:
Error: Symbol numeric_limits is not defined in current scope treetest.C:85:
Error: Symbol float is not defined in current scope treetest.C:85

I can use g++ to compile programs with numeric_limits. I added the limits header files into the code and it did not work either.
:frowning: How can I correct this? Thank you very much.

regards,

gma

Hi,

Your script compiled for me with the headers#include "TTree.h" #include "TFile.h" #include "TROOT.h" #include <iostream> #include <fstream>and the following changes:[code]< bool string2double(char* digit, double& result) {

using namespace std;

bool string2double(const char* digit, double& result) {
55c59
< ifstream in(“test.dat”);


std::ifstream in(“test.dat”);[/code]

So I suspect your version of gcc is older and you may have to make sure it is supporting the numeric limit feature you are using (and how so).

Cheers,
Philippe.

Hi,Philippe.
Thank for your answers. I am struggling in installing root 5.16 on my laptop now. Once I am done, I will test your solutions. And let you know what happened.

cheers,
Gma

Philippe,
Though it is late to answer you back. I came back to this question again. And adding TROOT.h solved my problem. Thanks.

cheers.

gma