Feature #6590

Some helpers for ROOT

Added by Rob Kutschke about 6 years ago. Updated almost 5 years ago.

Target version:
Start date:
Due date:
% Done:


Estimated time:
4.00 h
Spent time:
SSI Package:


When a user wants to create a histogram or tree object in the TFileService output file, all one needs to do is to be in the correct TFileDirectory and new the object. For other sorts of ROOT objects, such as TGraphs, there are additional steps:

  art::ServiceHandle<art::TFileService> tfs;

  gIntersections_ = tfs->make<TGraph>();
  gDirectory->Append(gIntersections_ );

Is there an appropriate place in art or a related utility to add a helper to look after this? I can see it either as a free function, a free function template or as a new member function template in TFileService. There are probably other options. What ever we do, we need to remember that TGraph has several constructors and all would have to work.

Some people do this differently. They create the TGraph in at begin time and then call write on it at the end time. I like the gDirectory->Append since it puts everything in a single spot.

Associated revisions

Revision ac43203e (diff)
Added by Marc Paterno over 5 years ago

Use variadic template in TFileService, add test, and implement issue #6590.

Finish storage of registerable things


#1 Updated by Jim Kowalkowski about 6 years ago

  • Category set to Infrastructure
  • Status changed from New to Accepted
  • Target version set to 1.13.00
  • Experiment Mu2e added
  • Experiment deleted (-)
  • SSI Package art added
  • SSI Package deleted ()


#2 Updated by Christopher Green over 5 years ago

  • Status changed from Accepted to Feedback
  • Assignee set to Marc Paterno
  • Estimated time set to 4.00 h

We believe that the code can be trivially cleaned up and made more general, with TGraph-specific specialization to handle the case you mention.

Are there any other ROOT classes of which you are aware for which similar behavior is required?

#3 Updated by Rob Kutschke over 5 years ago

I can't think of obvious canididates.

A few come to mind: TText, TAxis, TCanvas but I can imagine use cases in which people do not want these to be automatically stored. I have never encountered a case of someone wanting a transient TGraph.

The use case that I have in mind for the first two is to make text bin labels for a histogram: for example a histogram of the PDGId numbers (or names) of which particles created how many hits. Right now I can fill the histograms but I need to do a lot of gymnastics to get the bin labels over to the code that will plot the histograms.

#4 Updated by Marc Paterno over 5 years ago

  • % Done changed from 0 to 50

Some code cleanup was needed before adding the new features. This turned up the fact that the test code for TFileService was not being compiled or run. There is now a test that builds and runs a module that exercises the TFileService, and that makes sure that histograms it creates are put into the appropriate directories.

#5 Updated by Marc Paterno over 5 years ago

  • Status changed from Feedback to Resolved
  • % Done changed from 50 to 100

#6 Updated by Kyle Knoepfel over 5 years ago

  • Start date changed from 07/03/2014 to 02/04/2015

#8 Updated by Christopher Green over 5 years ago

  • Status changed from Resolved to Closed

#9 Updated by Christopher Backhouse almost 5 years ago

What was the resolution here exactly? I can't figure it out from the linked commit. Is there now an easier way to put a TGraph in the TFileService, or do I still have to go through the dance Rob gives in the original report?

#10 Updated by Rob Kutschke almost 5 years ago

To use it:

 art::ServiceHandle<art::TFileService> tfs;

 TGraph* tg = tfs->makeAndRegister<TGraph>( "name", "title");

This does exactly the sequence of operations above. If the c'tor of the ROOT object has arguments, you can provide them as additional arguments:
 TFoo* tg = tfs->makeAndRegister<TFoo>( "name", "title",arg1, arg2, arg3);

This passes (arg1, arg2, arg3) to the c'tor of TFoo; it then sets the name and title and does the append.

I don't know what happens if you use makeAndRegister on a type that ROOT automagically registers, such as TH1F or TTree:

 TH1F* th = tfs->makeAndRegister<TH1F>( "name", "title", "name", "title", nbins, xlow, xhigh);

Hopefully the need to repeat name and title will be a red flag. If you omit the repeated name and title I THINK you will get a compiler error saying that it cannot convert the double xlow to a const char*.

#11 Updated by Christopher Backhouse almost 5 years ago

Got it. Thanks!

Also available in: Atom PDF