Reading from a text file: What is wrong?


ROOT Version: 6.16/00
Platform: MacOS Mojave
Compiler: Not Provided


I am trying to read and extract some numbers from a txt file. I wrote a code which worked correctly under root 5.34, but I recently upgraded to 6.16 and it appears to be broken now. Here is what I have (shortly)

#include <math.h>
#include <iostream>
#include <string>

#define nAD 2

void main()
{
    const int NB = 27; 
    double s2th_13;
    double dm2_ee;
    double spc[nAD][NB];
    double NoscTot[nAD];
    int iAD;

    ifstream grid_file;
    grid_file.open("./files/gridSpectra.txt"); //(this file has many lines, each having 31 number I need to read)
    std::cout << "Is the file open? \t";
    if (grid_file.is_open() == 1)
        std::cout << "Yes! \n" << std::endl;
    else
        std::cout << "No! Check it out! \n" << std::endl;
  
    while (grid_file >> iAD >> s2th_13 >> dm2_ee  >> spc[iad][0] >> 
spc[iad][1] >> spc[iad][2] >> spc[iad][3] >> spc[iad][4] >> spc[iad][5] >> 
spc[iad][6] >> spc[iad][7] >> spc[iad][8] >> spc[iad][9] >> spc[iad][10] >>
spc[iad][11] >> spc[iad][12] >> spc[iad][13] >> spc[iad][14] >> spc[iad][15] >> 
spc[iad][16] >> spc[iad][17] >> spc[iad][18] >> spc[iad][19] >> spc[iad][20] >> 
spc[iad][21] >> spc[iad][22] >> spc[iad][23] >> spc[iad][24] >> spc[iad][25] >> 
spc[iad][26] >> NoscTot[iad])
    {//file loop
        std::cout << "Inside the while loop!" << std::endl;
        // Some stuff is done here...
    }
    
  return 0;
}

The problem is the code is not reading the numbers or getting inside the file, I think. Nothing inside the “while” loops is actually performed, and I don’t understand why.

I’ve been looking for information here in the forum, and applying some of the suggestions for similar situations. I haven’t have any success so far.

I’d appreciate any help.

Thanks!

Hi,
what’s the name of the file? If you execute a root macro with root mymacro.cpp, the function that you want to be executed must be called mymacro, like the file.

Cheers,
Enrico

Hi Enrico,

Thanks for your reply. I actually changed that part here. My main function has a different name (int reno_spect()) and my macro/file is called reno_spect.C, as you suggest.

Best,
Mario AAO.

Do you see the “Yes” message? do you get any error messages? which?
By the way, you define iAD but in “while” you use iad; this won’t work.
Other than this, it could also be that NoscTot[iad] is out of range (iad>=nAD), so you should also protect the code against this.

Hi,
Yes, the “Yes” message is printed. But I made a mistake by changing some stuff in the part of the code I posted here. Sorry about that.
The next lines show exactly as I have it:

#include "constants.h"
#include <math.h>
#include <iostream>
#include <string>
//---*****************************************************************************---//
//------------------------ CONSTANTS ------------------------------------------------//
//---*****************************************************************************---//
#define nAD 2
double s2th_13; //oscillation parameter to be fitted
double dm2_ee;   //oscillation parameter to be fitted
double spc[nAD][NB];
double NoscTot[nAD];
int iAD;
int RENO_minuit_spect()
{
    cout << "Reading file - Loop in progress..." << endl;
    ifstream grid_file;
    grid_file.open("./files/RENO_gridOscSpectra_test.txt");
    std::cout << "Is the file open? \t";
    if (grid_file.is_open() == 1)
        std::cout << "Yes! \n" << std::endl;
    else
        std::cout << "No! Check it out! \n" << std::endl;
    int iad = 0;
  
    while (grid_file >> iAD >> s2th_13 >> dm2_ee  >> spc[iad][0] >> spc[iad][1] >> 
                spc[iad][2] >> spc[iad][3] >> spc[iad][4] >> spc[iad][5] >> spc[iad][6] >> 
                spc[iad][7] >> spc[iad][8] >> spc[iad][9] >> spc[iad][10] >> spc[iad][11] >> 
                spc[iad][12] >> spc[iad][13] >> spc[iad][14] >> spc[iad][15] >> spc[iad][16] >> 
                spc[iad][17] >> spc[iad][18] >> spc[iad][19] >> spc[iad][20] >> spc[iad][21] >> 
                spc[iad][22] >> spc[iad][23] >> spc[iad][24] >> spc[iad][25] >> spc[iad][26] >> 
                NoscTot[iad])
    {//file loop
        std::cout << "Inside the while loop!" << std::endl;
        
        if (!grid_file.good()){
            std::cout << "\n \t File is not good! \n" << std::endl;
            break;
        }
        
        cout << " spc = " << spc[0][26] << endl;
        //Here I perform some evaluations with the numbers I'm reading in the loop
        iad++;
    }    
    std::cout << "Succesful run!!" << endl;
    grid_file.close();

    return 0;
}

And this is what I get after executing it (root -b -l -n -q RENO_minuit_spect.C):

Reading file - Loop in progress...
Is the file open? 	Yes! 

Succesful run!!

So, as you can see (if I’m making things more clear now), it is opening the file but nothing inside the while loop is executed.

In case this is useful, the following lines show the structure of the file I want to read:

1 6.95e-310 6.94e-310   98494.00   138037.00   174801.00   208353.00   237357.00   258357.00   275161.00   281847.00   282413.00   279508.00   267610.00   252612.00   237130.00   217169.00   197348.00   178047.00   157754.00   140650.00   123423.00   108318.00    94332.00    80303.00    67598.00    56924.00    83381.00    66776.00    28800.00  4592503.00
2 6.95e-310 6.94e-310    9301.00    12996.00    16264.00    19546.00    22196.00    24114.00    25768.00    26276.00    26565.00    25836.00    24937.00    23668.00        0.00    19892.00    18495.00    16476.00    14711.00    13079.00    11657.00     9924.00     8863.00     7553.00     6387.00     5489.00     7926.00     6062.00     3516.00   407497.00

1 1.00e-02 1.20e-03 98442.42188 137991.01562 174767.10938 208329.04688 237343.70312 258344.25000 275150.03125 281837.87500 282406.56250 279502.87500 267606.68750 252608.89062 237127.00000 217166.28125 197345.56250 178045.15625 157752.43750 140648.59375 123422.14062 108317.21875 94331.20312 80302.25000 67597.28125 56923.34766 83380.42969 66775.59375 28799.78906 4592264.75
2 1.00e-02 1.20e-03 9201.76367 12876.15918 16133.25391 19408.34180 22058.43945 23978.99805 25641.36914 26162.99414 26459.35547 25739.93555 24850.86914 23597.00195    0.00000 19843.39844 18453.53516 16441.30859 14681.69922 13053.97949 11636.10352 9907.52051 8849.41797 7542.08936 6378.23193 5482.04736 7916.95752 6055.85449 3513.19336  405863.82

So, I think iad would be equal to 0 an 1, while nAD takes 1 and 2 as possible values. But the last one is only a reference to me, telling me which line is the code reading.

Hopefully, with this additional information you could provide other ideas?

Hi,
uhm…I took your code as-is, just removed #include "constants.h" and added #define NB 27. I also changed the filename to just file.txt, and copy-pasted the data you provided inside…and it works:

~ root -l -b -n -q RENO_minuit_spect.cpp                                                           (tvem) 

Processing RENO_minuit_spect.cpp...
Reading file - Loop in progress...
Is the file open? 	Yes! 

Inside the while loop!
 spc = 28800
Inside the while loop!
 spc = 28800
Inside the while loop!
 spc = 28800
Inside the while loop!
 spc = 28800
Succesful run!!
(int) 0

So I’m stumped. The code seems fine. The only suggestion I have to debug this is to break that while condition in smaller statements that you can individually check (e.g. by printing the content of the first line, one value at a time) so you can see where things go wrong.

P.S.
here’s a version of the program that you can compile and run e.g. with g++ -o foo foo.cpp && ./foo. You’ll notice that there is no dependency on ROOT anymore, this is just a standalone C++ program. It runs correctly for me. You can execute it step by step with a debugger, e.g. with g++ -g -o foo foo.cpp && gdb ./foo and see at what point things go wrong.

// foo.cpp
#include <math.h>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

#define NB 27
#define nAD 2

double s2th_13; //oscillation parameter to be fitted
double dm2_ee;   //oscillation parameter to be fitted
double spc[nAD][NB];
double NoscTot[nAD];
int iAD;

int RENO_minuit_spect()
{
    cout << "Reading file - Loop in progress..." << endl;
    ifstream grid_file;
    grid_file.open("./file.txt");
    std::cout << "Is the file open? \t";
    if (grid_file.is_open() == 1)
        std::cout << "Yes! \n" << std::endl;
    else
        std::cout << "No! Check it out! \n" << std::endl;
    int iad = 0;
  
    while (grid_file >> iAD >> s2th_13 >> dm2_ee  >> spc[iad][0] >> spc[iad][1] >> 
                spc[iad][2] >> spc[iad][3] >> spc[iad][4] >> spc[iad][5] >> spc[iad][6] >> 
                spc[iad][7] >> spc[iad][8] >> spc[iad][9] >> spc[iad][10] >> spc[iad][11] >> 
                spc[iad][12] >> spc[iad][13] >> spc[iad][14] >> spc[iad][15] >> spc[iad][16] >> 
                spc[iad][17] >> spc[iad][18] >> spc[iad][19] >> spc[iad][20] >> spc[iad][21] >> 
                spc[iad][22] >> spc[iad][23] >> spc[iad][24] >> spc[iad][25] >> spc[iad][26] >> 
                NoscTot[iad])
    {//file loop
        std::cout << "Inside the while loop!" << std::endl;
        
        if (!grid_file.good()){
            std::cout << "\n \t File is not good! \n" << std::endl;
            break;
        }
        
        cout << " spc = " << spc[0][26] << endl;
        //Here I perform some evaluations with the numbers I'm reading in the loop
        iad++;
    }    
    std::cout << "Succesful run!!" << endl;
    grid_file.close();

    return 0;
}

int main()
{
   RENO_minuit_spect();
   return 0;
}

Cheers,
Enrico

Hi Enrico,

What version of root do you have? I’m using 6.16, but I’ve also used another machine with root 5.34 and it runs there!
That’s why I’m so confused about all this.

Thanks,

Mario AAO.

Oh… I did not read your last message correctly… I now see the “no dependence on ROOT”…

This was with current master, i.e. v6.19. It really should not depend on the ROOT version though.

I just tried on lxplus with ROOT v6.16 (got it with source /cvmfs/sft.cern.ch/lcg/views/LCG_95a/x86_64-centos7-gcc8-opt/setup.sh) – the code I shared still runs correctly (I had to rename foo.cpp to RENO_minuit_spect.cpp of course).

Printing out iAD using your 4 lines of the text file, I get:

Inside the while loop!
 spc = 28800	 iAD = 1
Inside the while loop!
 spc = 28800	 iAD = 2
Inside the while loop!
 spc = 28800	 iAD = 805306368
Inside the while loop!
 spc = 28800	 iAD = 2
Succesful run!!

But it should be 1 or 2. So there could be some issue with the values.

Well, it makes me think the problem is with the file I’m reading, actually. Maybe its structure?
I’ll have a look.
Thanks!

Well, it depends on how many lines the file actually contains. If it contains only 2 lines (if the four lines are 2 different files and not one, as I assumed) then it should work fine. If it contains more, just change the nAD definition value :slight_smile:

What happens if you run this code (save as RENO.C and run with ROOT) and the attached file.txt?

#include <math.h>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

#define NB 27
#define nAD 20

double s2th_13; //oscillation parameter to be fitted
double dm2_ee;   //oscillation parameter to be fitted
double spc[nAD][NB];
double NoscTot[nAD];
int iAD;

int RENO()
{
    cout << "Reading file - Loop in progress..." << endl;
    ifstream grid_file;
    grid_file.open("./file.txt");
    std::cout << "Is the file open? \t";
    if (grid_file.is_open() == 1)
        std::cout << "Yes! \n" << std::endl;
    else
        std::cout << "No! Check it out! \n" << std::endl;
    int iad = 0;
  
    while (grid_file >> iAD >> s2th_13 >> dm2_ee  >> spc[iad][0] >> spc[iad][1] >> 
                spc[iad][2] >> spc[iad][3] >> spc[iad][4] >> spc[iad][5] >> spc[iad][6] >> 
                spc[iad][7] >> spc[iad][8] >> spc[iad][9] >> spc[iad][10] >> spc[iad][11] >> 
                spc[iad][12] >> spc[iad][13] >> spc[iad][14] >> spc[iad][15] >> spc[iad][16] >> 
                spc[iad][17] >> spc[iad][18] >> spc[iad][19] >> spc[iad][20] >> spc[iad][21] >> 
                spc[iad][22] >> spc[iad][23] >> spc[iad][24] >> spc[iad][25] >> spc[iad][26] >> 
                NoscTot[iad])
    {//file loop
        std::cout << "Inside the while loop!" << std::endl;
        
        if (!grid_file.good()){
            std::cout << "\n \t File is not good! \n" << std::endl;
            break;
        }
        
        cout << " spc = " << spc[iad][26] << "\t iAD = " << iAD << endl;
        //Here I perform some evaluations with the numbers I'm reading in the loop
        iad++;
    }    
    std::cout << "Succesful run!!" << endl;
    grid_file.close();

    return 0;
}

file.txt (1.4 KB)

So, this is starting to driving me crazy.
I just did what you did. I created this short version of my code, twice. One to be compiled, and the other to be executed directly with ROOT. I both cases I’m still getting the same result.
I’m starting to think that, as you say, this does not have anything to do with ROOT.

Thanks dastudillo,
The result is exactly the same, unfortunately.

> root -b -n -l -q RENO.C 

Processing RENO.C...
Reading file - Loop in progress...
Is the file open? 	Yes! 

Succesful run!!
(int) 0

:cry:

I guess you never enter the while loop because one of the >> operator calls fails (can’t read the values for some reason). So it might very well be a problem with your file. Copy-pasting the data you provided into a file worked for me, though – maybe there is a problem with new line delimiters (e.g. if the file was created on windows and now you are reading it on linux)? Those are usually tricky and invisible.

I suggest to keep ROOT out of the equation by just compiling and running the program.
You can remove/comment out everything that is not related to opening the file and reading the first line.
Also remove the while loop.

Can you successfully read the first line of the file this way? If not, how many values can you read before you have a problem?

Well, I think I found the problem. And it is very much related to what Enrico was suggesting: there is an issue with the file.

I myself am creating the file I’m trying to read here, with a different code. It turns out that, to create the file, I was using C's functions/commands (fprintf(file," %10.2f ",contNO), for instance). For the reading part here, I use C++'s functions/commands (). Apparently, my reading code didn’t like that. Does this actually make sense?

On the other hand, the first thing I realized was that the number 6.95e-310 was affecting the reading from the very beginning. I changed it for a plain 0, and it worked just fine.

I’m not sure this is actually a definite solution, but for now it seems to be working. Thank you much, Enrico and dastudillo for taking some time on this!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.