AccessPathName to know if a file exists

Hello all.

I have a question about the AccessPathName command and how to know if a file exists.

I tried this command on the terminal: root [0] gSystem->AccessPathName(“nomefile”)
If the file exists, the terminal says: (Bool_t)0
If it doesn’t exist, it says: (Bool_t)1

This is what I was expecting to have… but I want to do a similar thing inside a program that I want to launch through .x name_of_program.C.

I want to do this check:

if (“commands to know if the file exists”) {
do some things…
}

but I don’t know how to use AccessPathName in this case.
Does anyone know the exact commands to put inside the program?

Thank you.

Are you looking for something like this?

#include <iostream>
#include <TSystem.h>

void name_of_program(){
    
    if(gSystem->AccessPathName("test.txt")){
        std::cout << "test does not exist" << std::endl;
    } else {
        std::cout << "test exists" << std::endl;
    }
    
    
    if(gSystem->AccessPathName("foo.txt")){
        std::cout << "foo does not exist" << std::endl;
    } else {
        std::cout << "foo exists" << std::endl;
    }
    
}
1 Like

I tried with if(gSystem->AccessPathName… but it didn’t work.

At the end I found another method:

myfile.open;
if (myfile.fail()) { … do something …}
else { … do other things …}

In each case thank you for your answer :slight_smile:

The macro @samcarter suggested looks fine seems to me. Have you tried it ? what is not working for you ?

I tried another time and it worked, but now I have another problem:

the AccessPathName works fine when I put the name of the file, like: AccessPathName(“name_of_the_file”)

but it doesn’t work when I try something like this:

ifstream myfile1;
string myfile1;
myfile1 = "name_of_the_file";

and then:

AccessPathName(myfile1)

I need this because I must open many file in a loop (each one different only for a number, like file1, file2, file3 and so on) and so I need to index the file names.

In the loop I used:

sprintf(filename, "name_of_file%i", i);
ifstream myfile (filename);

and then I tried:

if (gSystem->AccessPathName("name_of_file%i", i){cout ...}

but it doesn’t work!

You need to use c_str():

root [0] string myfile1;
root [1] myfile1 = "name_of_the_file";
root [2] printf("%s\n",myfile1.c_str())
name_of_the_file
(int) 17
root [3] 

ie:

gSystem->AccessPathName(myfile1.c_str());

Ok… but this not solve my problem with many files in a cycle… probably I miss something.

I tried this:

ifstream myfile1;
string filename1;
filename1 = "file5.txt";
myfile1.open (filename1.c_str());
if(gSystem->AccessPathName(filename1.c_str())){
   cout << "The file doesn't exists\n";
   } else {
     cout << "The file exists\n";
     for (int i=0; i<65; i++) {
           if (i==0) {getline(myfile1,line1);}
           else {myfile1 >> read >> what >> is >> inside;
                    cout << write << "\t" << what << "\t" << is << "\t" << inside << "\n";
                   }
     }
   }

and it worked perfectly.

But I need to do the same for many files to open and control inside a cycle… and I can’t do this in the same way (I can’t use: nomefile1, nomefile2…) then I tried this:

for(int j=0; j<34; j++){
     ifstream myfile;
     string filename;
     sprintf(filename, "file%i.txt", j);
     myfile.open (filename.c_str());
     if(gSystem->AccessPathName(filename.c_str())){
     cout << "The file doesn't exist\n";
     }  else {
     cout << "The file exists\n";
     for (int i=0; i<65; i++) {
           if (i==0) {getline(myfile,line1);}
           else {myfile >> read >> what >> is >> inside;
                    cout << write << "\t" << what << "\t" << is << "\t" << inside << "\n";
                   }
     }
   }
}

and it didn’t work.
The terminal gave me:

Error: sprintf parameter mismatch param[0] C u C:\path\of\program(92)
*** Interpreter error recovered ***

and the line 92 is the one with the command sprintf

You can make it simpler using Form :

for (int j=0; j<34; j++) {
   ifstream myfile;
   if(gSystem->AccessPathName(Form("file%d.txt",j))){
      cout << "ERROR: The file doesn't exist\n";
   } else {
      myfile.open(Form("file%d.txt",j));
      cout << "The file exists\n";
      for (int i=0; i<65; i++) {
         if (i==0) {
            getline(myfile,line1);
         } else {
             myfile >> read >> what >> is >> inside;
             cout << write << "\t" << what << "\t" << is << "\t" << inside << "\n";
         }
      }
   }
}
1 Like

Thank you!
It solved the problem!

With the previous construction I still had a problem:

Error: String literal syntax error C:\path\of\program(112)
*** Interpreter error recovered ***

where 112 is the line with the command:

if(gSystem->AccessPathName(filename.c_str())){

But with the Form constructor all is perfect.

Another time thank you (I was thinking on it from 3 days :D); sorry, but I’m not very expert with root and c++… I’m learning while I’m writing programs.

I have another question for the same program.

I need to plot an histogram for each file I opened.

When I made the program for each file I used:

  TH1D *h5 = new TH1D("h5","Histogram for file 5",53,-26.5,26.5);
  TH1D *h6 = new TH1D("h6","Histogram for file 6",53,-26.5,26.5);
  TH1D *h7 = new TH1D("h7","Histogram for file 7",53,-26.5,26.5);
  ...

at the beginning and then, for each file, I wrote:

h5->Fill (variable);
mean = h5->GetMean();
rms = h5->GetRMS();
outputfile << "\t\t" << mean << "\t\t" << rms << " \n";

and then, at the end:

  h5->Draw("");
  Double_t par[9];
   TF1 *g5 = new TF1("g5","gaus",-26.5,26.5);
   g5->SetLineColor(2);
   h5->Fit(g5,"R");
  new TCanvas();

Now I need to modify all the fields with numbers (5,6,7,…); if is it possible to use a method like the one used to open all the files, how could I write it?
thank you

TF1 *g = new TF1("g", "gaus", -26.5, 26.5);
Int_t i_max = 10;
for (Int_t i = 0; i < i_max; i++) {
  TH1D *h = new TH1D(TString::Format("h%d", i),
                     TString::Format("Histogram for file %d", i),
                     53, -26.5, 26.5);
  // ...
  h->Fit(g, "R");
  // ...
}
1 Like

Thank you Wile_E_Coyote.
It solved my problem: I didn’t find the correct expression of Format command before your answer.

I have only one last problem, regarding TCanvas:

after I put the command h->Fit(g, "R");, if I don’t use new TCanvas();, obviously the program plots only the last histogram;

instead, if I use new TCanvas();, the program give me to me many Warning:

Warning in <TCanvas::ResizePad>: c1_n3 width changed from 0 to 10
Warning in <TCanvas::ResizePad>: c1_n3 height changed from 0 to 10
Warning in <TCanvas::ResizePad>: c1_n4 width changed from 0 to 10
Warning in <TCanvas::ResizePad>: c1_n4 height changed from 0 to 10

and it doesn’t plot any histogram.

The last time I saw such errors was when the “system.rootrc” file was missing in the subdirectory returned by root-config --etcdir (i.e. often ${ROOTSYS}/etc). Actually, in that time, the whole subdirectory itself was missing due to some ROOT building / installing misconfiguration.

BTW. Before the “Fit” line, try to add:

new TCanvas(TString::Format("c%d", i));

Unfortunately nothing changes adding that command.

In my opinion it’s strange because in the program I did before, I used many new TCanvas(); lines and all was ok… now that the same line is inside the loop, it gives me the warnings.

Can you provide a small macro reproducing the problem ?

Sure.
I just made a simpler and smaller version of the same program, that makes similar things and gives the same problem with or without TCanvas.

#include <iostream>
#include <fstream>
#include <string>
using namespace std;


void Prova() {


  int pixel;
  double lg_sat, hg_sat_exp, hg_sat_meas;
  char line1[100];
  double mean, rms;


  //Creating files
  ofstream hfile5;
  string filename5;
  filename5 = "prova5.txt";

  ofstream hfile11;
  string filename11;
  filename11 = "prova11.txt";

  ofstream hfile30;
  string filename30;
  filename30 = "prova30.txt";

  ofstream hfile;
  string filename;
  filename = "provafin.txt";


  //Filling new files
  hfile5.open (filename5.c_str());
  hfile11.open (filename11.c_str());
  hfile30.open (filename30.c_str());


  hfile5 << "pixel\t\tLG_sat\t\tHG_sat_exp\t\tHG_sat_meas\n";
  hfile11 << "pixel\t\tLG_sat\t\tHG_sat_exp\t\tHG_sat_meas\n";
  hfile30 << "pixel\t\tLG_sat\t\tHG_sat_exp\t\tHG_sat_meas\n";

  for (int z=0; z<64; z++) {
      int k = z+1;
      hfile5 << k << "\t\t" << (k*0.1) << "\t\t" << (k*2) << "\t\t" << (k*2.1) << " \n";
      hfile11 << k << "\t\t" << (k*0.2) << "\t\t" << (k*3) << "\t\t" << (k*2.2) << " \n";
      hfile30 << k << "\t\t" << (k*0.3) << "\t\t" << (k*4) << "\t\t" << (k*2.3) << " \n";
      }

  //Closing files
  hfile5.close();
  hfile11.close();
  hfile30.close();



  //Making final histogram

  TH1D *htot = new TH1D("htot","Histogram for all files",53,-26.5,26.5);

  TF1 *g = new TF1("g","gaus",-26.5,26.5);     //command for fit


  //Opening last file
  hfile.open (filename.c_str(), ios::out);

  hfile << "File\t\tMean\t\tStd\n";


  for (int j=0; j<34; j++) {     //loop for all existing files

      ifstream myfile;     //opening files

      if (j==0) {printf("\n");}

      else if(gSystem->AccessPathName(Form("prova%d.txt",j))){          //controls if exists
              printf("\n\n File %i not found\n",j);}

      else {printf("\n\n File %i \n",j);
            myfile.open(Form("prova%d.txt",j));

            TH1D *h = new TH1D(TString::Format("h%d", j),                      //making histograms for existing files
                               TString::Format("Histogram for file %d", j),
                               53,-26.5,26.5);

            for (int i=0; i<65; i++) {     //loop for all lines

                if (i==0) {getline(myfile,line1);}     //jump first line

                else {myfile >> pixel >> lg_sat >> hg_sat_exp >> hg_sat_meas;     //reading file
                      h->Fill (lg_sat);     //filling histogram of each file
                      htot->Fill (lg_sat);     //filling final histogram

                     }
             }


      mean = h->GetMean();    //taking mean of single histograms
      rms = h->GetRMS();      //taking rms of single histograms

      hfile << j << "\t\t" << mean << "\t\t" << rms << " \n";     //filling new file with mean and rms of each file


      //Plotting histograms


      h->Draw("");
      Double_t par[9];
       g->SetLineColor(2);
       h->Fit(g,"R");
       h->GetXaxis()->SetTitle("[ (G_exp - G_meas) / G_exp ] (%)");
       h->GetYaxis()->SetTitle("counts");

//      new TCanvas();          <<<---------- THIS IS THE CONTROVERSE LINE!


      }

      myfile.close();      //closing files

  }



//Writing final datas on final file

  hfile << "\n";
  mean = htot->GetMean();
  rms = htot->GetRMS();
  hfile << "Sum\t\t" << mean << "\t\t" << rms;



//Plotting final histogram

  new TCanvas();
  htot->Draw("");
  Double_t par[9];
   TF1 *gtot = new TF1("g","gaus",-26.5,26.5);
   gtot->SetLineColor(2);
   htot->Fit(gtot,"R");
   htot->GetXaxis()->SetTitle("[ (G_exp - G_meas) / G_exp ] (%)");
   htot->GetYaxis()->SetTitle("counts");





   cout << "all ok!";

//  return 0;
}

the txt files are missing

Prova.cxx (3.6 KB)

1 Like

Answer for couet:
??? I made a program that creates the txt files… all works… the only problem is the plotting of histograms in new TCanvas.

Answer for Wile_E_Coyote:
Thank you very much! Your code works perfectly!
I have only a question: why the program plots the histograms, even if it lacks of Draw commands?
It’s only curiosity to better understand all :slight_smile:
Is it due to #include commands?

TH1::Fit

1 Like