Is there a function to get the number of Trees in a root file?
Hi,
you can loop on the keys holding objects stored in a ROOT files and get their type name, e.g. “TTree” as follows:
for (auto&& keyAsObj : file->GetListOfKeys()){
auto key = (TKey*) keyAsObj;
cout << key->GetName() << " " << key->GetClassName() << endl;
}
if it is enough for you, you can achieve this with a command line utility, rootls
rootls myfile.root
Cheers,
D
Not sure this solution is addressing trees hidden in deep directories’ hierarchies. Is it?
Welcome to the Newbie category!
Here we take it easy and assume the case is the simplest possible
With recursion this would look like
void listRecursive(TDirectoryFile *f, unsigned int nindent = 0) {
const std::string indent(nindent, ' ');
for (auto &&keyAsObj : *f->GetListOfKeys())
{
auto key = (TKey *)keyAsObj;
cout << indent << key->GetName() << " " << key->GetClassName() << endl;
if (auto d = dynamic_cast<TDirectoryFile*>(key->ReadObj())) {
listRecursive(d, nindent + 2);
}
}
};
void myMacro()
{
TFile file("a.root");
listRecursive(&file);
}
but let’s not dive into solutions of problems if we do not know they exist!
Cheers,
D
People sometimes use TFolder based structures, which your scan does not cover (so, some trees may be missing in the list).
Also, if you scan TKey instances, you will get all “cycles” listed separately (so, some trees may appear many times in the list).
also, rootls
from ROOT doesn’t handle subdirs nor recursion:
$> root --version -b -q
------------------------------------------------------------
| Welcome to ROOT 6.14/04 http://root.cern.ch |
| (c) 1995-2018, The ROOT Team |
| Built for linuxx8664gcc |
| From tags/v6-14-04@v6-14-04, Aug 23 2018, 17:00:44 |
| Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------
$> rootls -t -l ./dirs-6.14.00.root
TDirectoryFile Jul 03 11:08 2018 dir1 "dir1"
TDirectoryFile Jul 03 11:08 2018 dir2 "dir2"
TDirectoryFile Jul 03 11:08 2018 dir3 "dir3"
groot/cmd/root-ls does
$> root-ls -t ./dirs-6.14.00.root
=== [./dirs-6.14.00.root] ===
version: 61400
TDirectoryFile dir1 dir1 (cycle=1)
TDirectoryFile dir11 dir11 (cycle=1)
TH1F h1 h1 (cycle=1)
TDirectoryFile dir2 dir2 (cycle=1)
TDirectoryFile dir3 dir3 (cycle=1)
It is not fully true. Try:
rootls "dirs-6.14.00.root:*"
I stand corrected
but it’s not super useful either:
$> rootls -l "dirs-6.14.00.root:*"
dir1 :
TDirectoryFile Jul 03 11:08 2018 dir11 "dir11"
dir2 :
dir3 :
$> rootls -l "dirs-6.14.00.root:*/*"
TH1F Jul 03 11:08 2018 h1 "h1"