Home | News | Documentation | Download

Problem using wildcards in TChain->Add


#1

_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


#2

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());
}

#3

It worked perfectly.

Thank you very much!


#4

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