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 TTree
s.
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 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?
@Wile_E_Coyote
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 TFolder
s 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?
@Wile_E_Coyote
I added recursive traversal of TFolder
s.
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
TPad
s. Note,TCanvas
inherits fromTPad
. - 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 thewhat I want
object from thefirst directory
directory. This doesn’t work in ROOT by simply callingfile.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 therootls
code, even if possible, would not be a productive endeavor. - Many user scripts may depend on the current behavior of
rootls
. They would break ifrootls
is removed. - Duplicating the output format of
rootls
is unnecessary ifrootls
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
.
Nice tool, thanks!
And one idea:
merging it with this terminal-like TBrowser would make it amazing
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.