Problem using wildcards in TChain->Add


_ROOT Version: root 6.14.04-x86_64-slc6-gcc62-opt
Platform: Not Provided
Compiler: Not Provided


Hi,

I got stuck using wildcards to add files in a TChain. When I tried to add all the root files stored in a directory (“main_dir”) I used:

chain->Add("path/to/main_dir/*");

and worked fine. But now, the files are in different subdirectories inside the main directory:

main_dir/subdir_1/*
main_dir/subdir_2/*
main_dir/subdir_3/*

I tried with:

chain->Add("path/to/main_directory/*/*");

but it didn’t work. I thinks it’s realted with the regex, but I couldn’t find a solution, and maybe you can help me.

Thanks in advance,
Gonzalo

The TChain::Add function doesn’t do globbing, but loops over all files in the specified directory and tries to match them. So no wildcards allowed for directories (wildcards are not even allowed for all types of filesystems). Documentation says Wildcard treatment is triggered by the any of the special characters []*? which may be used in the file name
So you need to loop all by yourself.

With ROOT:

auto dir = gSystem->OpenDirectory("main_dir");
while (auto f = gSystem->GetDirEntry(dir)) { 
  if (!strcmp(file,".") || !strcmp(file,"..")) continue;
  chain->Add(TString("main_dir/") + f + "/*.root");
}
gSystem->FreeDirectory(dir);

Or you can use globbing:

#include <glob.h>
std::vector<std::string> glob(const char *pattern) {
    glob_t g;
    glob(pattern, GLOB_TILDE, nullptr, &g); // one should ensure glob returns 0!
    std::vector<std::string> filelist;
    filelist.reserve(g.gl_pathc);
    for (size_t i = 0; i < g.gl_pathc; ++i) {
        filelist.emplace_back(g.gl_pathv[i]);
    }
    globfree(&g);
    return filelist;
}

for (const auto &filename : glob("path/to/main_directory/*/*.root")) {
    chain->Add(filename.c_str());
}

It worked perfectly.

Thank you very much!

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

See also this forum post, which links to a Jira issue that links to the PR that now implements this feature in ROOT itself: