Pass root file to C++ program in terminal command

Hi all,

I want to make it very easy to change which root file I’m analysing in my .cpp file by passing it as an argument when I launch the command from the terminal.
I’m not an expert, and the only way I know of to do it is the following:

int main(Int_t argc, char **argv){
 std::ofstream readfile;
    if(argc>1){
      readfile.open(argv[2],std::ofstream::out);//set file name
      std::cout<<"Setting truth file name to "<<argv[2]<<std::endl;
    }
 }  

But I don’t know how to then get access to the TTree within the root file that I pass it.

Is there a better way of opening the file as a TFile, or how’s the best way of getting access to the TTree?

Thanks

int main(Int_t argc, char **argv){
    std::string readfile;
    if(argc>1) {
      std::cout<<"Setting truth file name to "<<argv[1]<<std::endl;
       readfile = argv[1];
    }
    auto f = TFile::Open(readfile.c_str()); // edited
    if (!f || f->IsZombie()) {
      std::cerr << "Could not open the ROOT file: " << readfile << "\n";
      return 1;
    }
    auto tree = f->Get<TTree>("name_of_tree");
    if (!tree) {
      std::cerr << "Could not read the TTree: " << "name_of_tree" << "\n";
      return 2;
    } 
    // Use tree, see User guides, tutorials and TTree and RDataFrame documentation for more information.

 }  
1 Like

It gives me

**error:** **no matching function for call to 'Open'**

auto f = TFile::Open(readfile);

yes, there was a typo in my code, see above for the correct syntax.

1 Like

To piggy back off this question, I’d now like to ask how I can do something similar in a .C root macro. I’d like to either pass the root file to open as an argument when I run the script (root -l myscript.C rootfiletoopen.root) or if that’s not possible be prompted to type the required file into the terminal once the macro has been launched.
Can you help?

Hi,

try

root -l 'myscript.C("rootfiletoopen.root")'
1 Like

That works great!
For future reference to anyone else, my macro looks like this:

void TreeAnalysisMacro(TString firstilename, TString secondfilename){

  /*Open files and set up trees*/
  TFile *truthfile = TFile::Open(firstfilename,"read");
  if(truthfile==nullptr){
    std::cout<<"no truthfile"<<std::endl;
    return;
  } 
  TFile *derivfile = TFile::Open(secondfilename,"read");
  if(derivfile==nullptr){
    std::cout<<"no derivfile"<<std::endl;
    return;
  }

if (truthfile==nullptr || truthfile->IsZombie()) {

I wanted to understand the IsZombie() check better, so I went to the TFile class reference and found:

If the constructor fails in any way IsZombie() will return true

Why would the constructor fail if truthfile.root exists and therefore if(truthfile==nullptr) isn’t a sufficient check?

Because if the truthfile is corrupted, truthfile will not be a nullptr but truthfile->IsZombie() will return true.

You can check by yourself: take a ROOT file and corrupt it manually (i.e., open it in your favorite text editor and delete a few lines). The IsZombie() will return true whenever you try opening that file.

1 Like

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