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 
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.