Posts tagged ROOT

The audience is engrossed

Behind the scenes: how physics really gets done

1

As a non-physicist, you may think that physicists spend their time writing equations on chalkboards, tweaking complicated machines, or scribbling equations on chalkboards. If you read Dan Brown, you probably think they run around in white lab coats. However, hands-on work involving machines and equipment is often given to undergraduate interns and graduate students, while PhD physicists conduct their work a little differently…

  • CERN physicists spend most of their work day in meetings, not in labs or their offices.
  • There are so many meetings that committees have been formed to hold meetings to figure out how to reduce the number of meetings (I am not making this up).
  • Physics analysis is done on laptops during meetings, because it has to get done sometime, and physicists are always in meetings.
  • Nobody pays attention to the speaker because they’re submitting physics analysis jobs and creating ugly ROOT graphs on their laptops; they know they can always get the slides later from Indico, the conference management tool everybody uses to post their slides.
  • The presenters know nobody is listening so instead of creating readable PowerPoint slides or learning the most basic presentation skills, they write entire blocks of fully formed text in their PowerPoint slides using miniscule font sizes and read verbatim from the slides in an often inaudible monotone. They know that if anyone wants to see their results, they’ll just read the slides on Indico later. Generally the presenter faces the screen, with his/her back to the audience.

This behavior habitual and completely ingrained. I was once in a tutorial for physicists held in a computer lab, where every seat had a desk with a dedicated computer terminal. The participants all filed into the room, sat down at their computer terminals, got out their laptops, put them in front of the computer terminals, and plugged their laptops in at the same time, blowing the room’s electrical circuits.

TH1 class hierarchy

ROOT rants: histogram hierarchy and a little PyROOT

2

I was doing some Google searching a couples days ago looking for answers to a ROOT question–I have a new one every day!– and I stumbled on a very nice rant about ROOT. It mentions the ugly default plotting style of that was the focus of my last post, and it hits on many points I would have made myself.

Sorry, if you don’t have any programming experience this post might be too technical.  If so, may I instead offer you a large man on a small vehicle?

One thing I really liked is the comment about the crazy inheritance: how a 2D histogram (TH2) inherits from a 1D histogram (TH1). The reasoning for the ROOT authors seems to be that a 2D histogram can be thought of as a long 1D histogram “rasterized” onto a 2D field. In this (convoluted) way, the 2D histogram is a specific type of 1D histogram. But, as the author of that University of Minnesota page notes, there is no reason not to think of the relation going the opposite way: a 1D histogram is just a 2D histogram with only one bin in the second axis. And, this second relation seems a whole lot more obvious and fundamental. The structure the ROOT authors use doesn’t hurt them too badly because in reality most of the operations on histograms happen bin by bin. The implementation of an n-dimensional array very well may boil down to a 1D array; but, are we really doing the user any favors here?

TH1 class hierarchy

With a TH2 inheriting from a TH1 certainly you would assume there is one advantage: the TH1 class won’t be cluttered with nonsensical methods like GetNbinsY() or GetYaxis().  Of course you would be wrong, just check it out.  In fact, given the structure they’ve ended up with, I’m having a hard time coming up with a reason why they even need separate classes for 1D and 2D histograms.

And while I’m still speaking of histograms, the profusion of varieties must be noted: TH1C, TH1S, TH1I, TH1F, TH1D.  When I first started using ROOT and hadn’t yet carefully read the documentation I assumed a TH1I would be used to histogram an integer valued parameter, in other words the x-axis would take integer values.  Though most parameters we work with have continuous values, counts (usually called “multiplicities”) such as “how many electrons with energy greater than 10 GeV were in the event?” are also very important. Thus histograms over integer values would really fill a need. Of course, this is not what ROOT provides: all a TH1I does is promise to store each bin value (the number that defines the y-value on the graph) as an integer.  This doesn’t change the fact that a TH1I can only be Fill()ed using a floating point weight. The Fill() method, and nearly every other method on this class, is defined generically using doubles in the TH1 parent class.  Strangely, the functions for requesting a bin value are implemented in the integer specific TH1I class, so you might think that at least they would do the sensible thing and deal only in integers. Instead, the integer stored internally is cast as a double before being returned.   As far as I can tell, there is no way to get unadulterated integers, that you know must be in there, out of this class.  One might wonder if the different histogram varieties just offer different storage sizes, but then sizeof(Int_t) == sizeof(Float_t), so it’s unlikely.  Maybe there is a slight speed advantage when incrementing (though it is hard to imagine this is an issue with any processor having a dedicated floating point unit, taking us back at least 20 years)?  I don’t know, I give up.

I think this is enough ROOT ranting for now.  Possible topics for a further post

  1. How histograms and TTrees are owned by the directory they are created in (whereas similar objects like graphs are not).  When you are new to ROOT this is guaranteed to lead to mysterious segmentation faults.
  2. Code that runs without errors or warnings in both compiled and interpreted modes, but produces different results.
  3. The vector classes: why does the 2D vector have to use Mag() while the 3D vector uses Mod()
  4. Painful limitations to using STL classes like std::vector<> in interpreted mode.  (The reason I gave up on doing any substantial work using interpreted ROOT code.)
  5. Horrible crashing that  refuses to let you quit even with Ctrl-C.

Oh, and regarding my recent issue that lead me to Google for answers: I’ve been using PyROOT a lot lately, but the underlying C++ bites you in the ass now and then. One issue I ran into is functions that modify values passed by reference. Python was designed to avoid this sort of thing, at least for the fundamental types, and so you have to do some annoying array('i', [0]) machinations just to pass a reference to an integer into a function.  Thankfully this doesn’t happen often, and it turns out the ROOT manual does explain the work-around well enough if you look in the PyROOT section [PDF] on TTrees.  (Instead of a TTree, I was actually trying to use TColor::HLS2RGB(), mostly foolishly, I must say.)  On the whole, though, I would highly recommend PyROOT if you are doing anything high-level like making plots and you have to use ROOT.

2D histograms plotted with the default palette (left) and SetPalette(1) (right)

The ROOT of all my frustrations

12

If you work in high energy physics (HEP) you almost certainly come in contact with some software called ROOT on a very regular basis. ROOT is a collection of tools and a framework of C++ classes developed at CERN specifically for the data collection and processing that many physicists perform.  It defines a “Tree” format designed specifically for HEP data (the name is a play on the name ROOT and not much of a tree in the classic algorithms-and-data-structures sense), it produces nearly all the plots that we show each other at meetings, and it provides a C++ environment that can be used both interactively and compiled.  (There is also a Python interface which I actually use more often these days.)  If you use something every day you are bound to become frustrated with it in some way or another.  Unfortunately, ROOT’s annoyances are very pernicious:

  1. Its default behavior is to produce hideous plots, and
  2. Every now and then you can come up with the simplest of goals (something such as “set the color of these histograms to red”) that teases you with the prospect of an easy solution but instead sucks you into a whirlwind of failure that invariably transports you to the colorful land of the ROOT source code where you search for a way home skipping from function call to function call until you find the solution didn’t make any sense at all but was right in front of you the whole time.  If you are luck enough to reach this point it is probably 4am.

These issues frustrate my personality especially because

  1. I’m particular when it comes to aesthetics, and
  2. I’m a stubborn optimist always willing to stay up just a little bit longer.

This post will feature a couple examples of item 1, but the infinitely long scroll of bits that this blog could fill is just barely long enough for the further rants I may produce.

Below is an example of two fitted histograms.  The left is a plot drawn with the default style and the right is using the “Plain” style.  There are two main issues with the default style: the uniform gray background makes it an eyesore on almost any white page or white presentation background, and the last time the chamfering and shadow effects were cool was back in 1995.  I have seen no circumstance in which the “Plain” style on the right wasn’t a clearly better choice.

Histograms plotted with the default (left) and "Plain" (right) styles

Histograms plotted with the default (left) and "Plain" (right) styles

What’s madding is the Plain style can be enabled with one simple line of code, and yet after I started using ROOT every day and was immediately struck by these offensive plots I went months between the stages of realizing

  1. The backgrounds of my plots are not just a stupid mistake on my part;
  2. I can fix this with five lines of boilerplate code at the top of all my programs;
  3. I can put this code in a configuration file that appears in every directory where I run;
  4. I can set a ROOT path and put this code in a single configuration file for my entire login session; and finally,
  5. That there are perfectly good styles build into the code called “Plain” and “Pub” that setup every as you wanted it to begin with using a single line of code.

These days when I see a presentation with these ugly gray backgrounds I presume the presenter has either not been using ROOT for very long (at least not long enough to produce a publication, since no publication would accept such plots), or they are still on stages 2 or 3 and the plots where made in a hurry.  Both of these scenarios are common.

What’s even more maddening is that I didn’t reach stage 5 by reading the documentation, which really needs to begin with

In order for your ROOT plots to not suck be sure to set a Unix.*.Root.MacroPath: in your ~/.rootrc file and then add gROOT->SetStyle(“Plain”); to a  rootlogon.C file somewhere in this path.

Admittedly, this style setting stuff is in the documentation, but a section called “Create or Modify a Style” is not one you would read too carefully when you are rushing to make plots for your next presentation.  Instead, I came upon the “Plain” and “Pub” styles by finding them in the source code while on one of those lovely journeys mentioned in item 2 of my opening.

Finally, here is another example of crap that ROOT gives you by default.  It’s possible the default plot offers some advantages to those who are color blind or to those who are 13 years old and are really trying to piss me off, but otherwise why?  Why?

2D histograms plotted with the default palette (left) and SetPalette(1) (right)

2D histograms plotted with the default palette (left) and gStyle->SetPalette(1) (right)

Go to Top