Getting filename from TTree or TChain

Dear ROOTers,

I need your help in getting the name of a file (a string) provided from a shell script to a TChain which is then used in a C++ code. The name of the file is needed in the C++ code.

I am running the following shell script:

#! /bin/bash
root_filename="/home/rbrener/Analysis/Run3_dilepton/QBH/analysis/ADD_4_0_3000.root"
root -l << EOF
.L BasicAnalyserAttempt.C++
TChain chain("LHEF")
chain.Add("$root_filename")
BasicAnalyserAttempt t(&chain)
t.Loop()
EOF

Inside the analysis code, BasicAnalyserAttempt.C, I am trying to get the $root_filename provided in the shell script — so far unsuccessfully.
The following: fChain->GetCurrentFile() returns 0 whereas fChain->GetCurrentFile()->GetName() prompts a segmentation violation.

It seems that my fChain is in fact a TTree (maybe due to this command in the shell script: TChain chain("LHEF")?) which is why the name of the file cannot be obtained straightforwardly?

I can provide further details (like the automatically-generated header file) upon request.

Any idea would be warmly welcomed!

Cheers,

Roy


_ROOT Version: 6.18/04
_Platform: linuxx8664gcc
_Compiler: root


Hi @roy.brener ,

if you execute those commands “by hand” in the root prompt do things work as expected?

If yes, the problem is likely in the bash variable expansion and it’s not as much related to ROOT but to bash scripting.

If not, can you please provide a small C++ reproducer for the problem with TTree/TChain?

Cheers,
Enrico

Hi @eguiraud,

Thanks for your reply.
If I add the following line in the shell command:
chain.GetFile()->GetName(),
I get what I want.
But the need is to get it from the actual C++ code used, as specified before.
Added a reproducer below.

Cheers,

Roy

#define BasicAnalyserAttempt_cxx
#include <iostream>
#include "BasicAnalyserAttempt.h"

void BasicAnalyserAttempt::Loop()
{
std::cout << "fChain->GetName()    " << fChain->GetName() << std::endl;
std::cout << "fChain->GetCurrentFile()    " << fChain->GetCurrentFile() << std::endl;
std::cout << "fChain->GetCurrentFile()->GetName()    " << fChain->GetCurrentFile()->GetName() << std::endl;
}

Hi @roy.brener ,

the reproducer is not self-contained so I cannot run it, but I can add some more information that might help you.

A TTree is a single dataset. A TChain is a vertical concatenation of (usually multiple) TTrees (so you get a larger logical dataset that has the same columns as the trees that make up the chain and the union of their rows).

A TTree will usually have one associated file (sometimes it will have no associated file, but that’s not relevant here). A TChain will have multiple associated files, and the current file depends on which entry is loaded in the chain, if any. Since you never loaded an entry in the chain, there is no current TTree, and no current file (that’s why fChain->GetCurrentFile() returns a null pointer (or 0), and then of course fChain->GetCurrentFile()->GetName() errors out because you are calling ->GetName() on a null pointer.

For your actual problem:

  • you can get a list of all files associated to the TChain with fChain->GetListOfFiles(), or maybe better
  • you can simply use a TTree

You can also call fChain->LoadTree(0) to load the tree that contains entry 0 in the chain and then fChain->GetCurrentFile() will return something meaningful.

I hope this helps!
Enrico

Hi @eguiraud,

Thanks so much! You solved it :slight_smile:

I used fChain->LoadTree(0) and then fChain->GetCurrentFile()->GetName() and indeed obtained the filename.

Cheers,

Roy

Good! As I mentioned if you always ever have a single tree anyways, you can simply just use a single tree instead of a TChain.

1 Like

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