Terminal program for printing ROOT file contents in a tree format

Dear fellow ROOT users.
I’ve developed a convenient program for looking at ROOT file contents in the terminal, with output that looks similar to that of tree. It can print the structure of directories inside a file as well as branches’ names and types in TTrees.
The program and more information can be found here: https://github.com/ivankp/rootbr
I’ve been using this program in its previous incarnation for several years now and have found it to be very convenient. Now, I’ve cleaned it up and implemented additional command-line options.
With this post, I would like to propose it for inclusion in the regular ROOT distribution.

Hi Ivan,

Thanks for the offer! How does it compare to ROOT’s current command-line tools such as rootls:

$ rootls -t tutorials/hsimple.root
TProfile  Mar 18 14:57 2021 hprof   "Profile of pz versus px"
TH1F      Mar 18 14:57 2021 hpx     "This is the px distribution"
TH2F      Mar 18 14:57 2021 hpxpy   "py vs px"
TNtuple   Mar 18 14:57 2021 ntuple  "Demo ntuple"
  px      "px"      100284
  py      "py"      100284
  pz      "pz"      100284
  random  "random"  100300
  i       "i"       100280
  Cluster INCLUSIVE ranges:
   - # 0: [0, 24999]
  The total number of clusters is 1

Cheers, Axel.

Hi Axel,
Thanks for pointing out the -t option of rootls. I wasn’t aware of it.

Here’s the output of my program for the same file.

$ rootbr tutorials/hsimple.root
TH1F hpx
└── TPaveStats stats
TH2F hpxpy
TProfile hprof
TNtuple ntuple [25,000]
├── Float_t px
├── Float_t py
├── Float_t pz
├── Float_t random
└── Float_t i

In comparison, the output is a bit terser. The number of events in the TNtuple is listed. (Edit: I see that rootls also prints the number of events, but I didn’t immediately guess what “Cluster INCLUSIVE ranges” means. Also, I tried rootls -t on one of our analysis MxAODs, and it printed 35446 lines of cluster ranges.)

rootls doesn’t print types of branches.
Something not obvious from the sample file is that rootls doesn’t print subdirectories.
These two are the main features of rootbr.

rootbr can print objects attached to histograms, as you can see with the TPaveStats. I’m planning on adding similar functionality for TCanvas.

rootbr has options for printing binning (-b) and integrals (-i) of histograms, so a user can easily inspect if histograms were defined correctly and got filled.
In my opinion, color coding makes the output a bit easier to interpret immediately.

I have additional long options for printing some basic TFile info:

--ls         call TFile::ls()
--map        call TFile::Map()
--streamer   call TFile::ShowStreamerInfo()

rootbr doesn’t print objects’ timestamps. That’s something I can add as an option.
I’m not sure what the numbers in the third column in the list of branches mean in the rootls -t output. If that’s useful information, I can add that too.

Some of the differences between rootls and rootbr are similar to those between tree and ls. There are situations where one suits better than the other. Maybe it’s a matter of taste. I have a couple of colleagues who like my version.

Please, let me know if you have any suggestions for how I can improve the program.
Thank you for expressing interest!

Super interesting, thanks! I believe it would be best if we could merge the functionality into rootls - there’s no point in having two tools doing mostly the same :slight_smile: Yes there’s ls and tree - but ls -r comes close…

I see rootbr is in C++ - do you think it’s worthwhile to move the code into rootls?

I also think merging is a good idea.
I can try to make a merged program, with one type of output used by default, and the other if a flag is passed. Then we could have the best of both worlds.

I’ll report back after I give it a go.

Please, post any additional comments in the meantime.


Oooooh that would be wonderful! Thank you SO much!

Sometimes, TFolder objects are stored in files (an example is present in an old thread). Would it be possible to add (recursive) “traversing” of such objects, too?

That is exactly what my program does.
See the example output in my readme.

I misspelled the class name in my previous post. Now corrected.

Huh. I’ll add a clause for them. It’s a very straightforward addition.
But I’ve never seen TFolders in a file before. Thanks for pointing out that that’s a possibility.
I’m wondering why we need more than one class to represent the directory concept in ROOT. We have TDirectory, TDirectoryFile, and TFolder. Are there any more?

I added recursive traversal of TFolders.
Turns out they are basically wrappers for TCollection pointers.

Since the last time I posted, I have added several features to the program, including:

  • Recursive traversal of TTree branches.
  • Inspection of objects contained in TPads. Note, TCanvas inherits from TPad.
  • Sorting of listed objects.
  • Options now toggle instead of setting. This reduces the number of distinct options necessary.
  • Objects’ timestamps can now be printed by passing the -T option.
  • Specific objects to inspect can now be at any level in the directory tree. Passing 'first directory/what I want' as a trailing argument now correctly retrieves the what I want object from the first directory directory. This doesn’t work in ROOT by simply calling file.Get("first directory/what I want"), apparently because both spaces and slashes are present.

Note that I had to change the names of some of the options since the last time I posted in order to make things more intuitive while I still have a chance before a larger number of people adopt the program.

After a lot of consideration, I’d recommend not merging my program with rootls. The author of several of the command line tools, including rootls wrote them as a monolithic python script with multiple front-end programs that simply parse the command line arguments and pass them to the right function in the monolithic script. Considering this and other factors listed below, I think that the best course of action would be to retain rootls for legacy use, and also provide the new program, which, if need be, can be renamed as the maintainers of the ROOT distribution see fit, potentially to rootls2.

Here are the reasons why I think merging rootbr and rootls is not a good idea:

  • rootls code is contained in a monolithic script, which other scripts depend on. Therefore, removal of the rootls code, even if possible, would not be a productive endeavor.
  • Many user scripts may depend on the current behavior of rootls. They would break if rootls is removed.
  • Duplicating the output format of rootls is unnecessary if rootls will not be removed.
  • Having an additional executable in $ROOTSYS/bin should not be a burden.
  • If the two programs were merged, either the old or the new behavior would have to be selected with an extra flag. If the flag --old is chosen, old scripts will need to be patched. If the flag --new is chosen, many users may never discover the new features, and the use of the utility becomes more cumbersome. Having two separate programs has neither of these drawbacks.

The updated utility can be found at the same GitHub repository.

Until rootbr is a part of the ROOT distribution, it can be easily added to an existing installation by running make install, which copies the compiled executable into $ROOTSYS/bin.

1 Like

Nice tool, thanks!

And one idea:
merging it with this terminal-like TBrowser would make it amazing :slight_smile:

1 Like

Thanks for pointing out this program. I was actually considering attempting to implement something similar to it as a separate program.
It’s a bit unfortunate that the author of rootbrowsetty made some questionable decisions concerning the choice of characters for drawing frames and histograms. I also noticed a lack of shortcuts (e.g. to search and navigate the file tree) and the presence of some glitches (histogram panel getting cut off if resized back and forth). But otherwise, it’s an awesome tool!

Concerning merging.
I tend to approach programming with the Unix philosophy in mind. That is, programs should do “one thing” and do that thing well.
So, while I totally agree that rootbrowsetty is a wonderful thing, and I wish a somewhat improved version of it was included with the root distribution, I don’t think that merging everything into one big program is the way to go.

1 Like