Finding all objects in a root file, regardless of directries

I’m trying to find a way in root to load a file and find all objects of a certain class (say, 'TCanvas’s). Using code that (I think) Rene posted here a while ago, I’ve got code that works well if the file is flat (i.e. no directory structure):

void listRootCanvases (TString filename = "TrigMon203153_tmp.root")
   TFile f(filename);
   TIter next(f.GetListOfKeys());
   TKey *key;
   //TCanvas c1;
   while ((key = (TKey*)next())) {
      TClass *clsPtr = gROOT->GetClass(key->GetClassName());
      TString name = key->GetClassName();
      if (! name.Contains("TCanvas")) continue;
      // do something with the key
      cout << ":::" << key->GetName() << ":::" << endl;


Unfortunately, this does not work on a file with directory structure. When I run this on a file that has directories, I don’t get anything (even the directories).

Is there either:

  • A way to list all objects regardless of directories, or

  • A way to systematically loop through all of the directories and getting all of the files in each directory?


see example below

[code]//file loopdir.C
void loopdir (TDirectory *dir) {
//loop on all keys of dir including possible subdirs
//print a message for all keys with a class TH1

TIter next (dir->GetListOfKeys());
TKey key;
while ((key = (TKey
)next())) {
if (strstr(key->GetClassName(),“TH1”)) {
printf (" key : %s is a %s in %s\n",
if (!strcmp(key->GetClassName(),“TDirectory”)) {
TDirectory *subdir = gDirectory;

Do, for example

root > TFile f("myfile with subdirs.root"); root > .L loopdir.C root > loopdir(&f);

That works beautifully. The CDF silicon group thanks you.