C++ macro to write Branch() for each variable in class

ROOT Version: 6.24/08
Platform: Ubuntu 20.04.6 LTS x86_64
Compiler: linuxx8664gcc


Hello everyone,

To create a tree of variables, I am defining a class with all the variable names. Here is the pseudocode:

class Tree_Maker
{
public:
  int A;
  double B[2];

  Tree_Maker(TTree *tree);
};

// for this part I want macro
Tree_Maker::Tree_Maker(TTree *tree)
{
  tree->Branch("A", &A, "A/I");
  tree->Branch("B", B, "B[2]/D");
}

As you can notice, I have to remember the constructor part each time I add a new variable. I have ~100 variables in this class. It happened many times that I forgot to add the branch and only realized that after one hour of execution time :frowning:

The closest thing I can think of is a macro that looks something like this:

// I haven't tested this macro. This is just an example
#define MAKE_BRANCH(x) tree->Branch("#x", &#x, "#x/I");

However, the best solution would be to have ROOT functionality that handles this type of job.

Any suggestions or comments would be a great help.

Thanks,
Divyang.

Hi @Divyang,

thank you for your question. First of all, I would like to ask you if you maybe considered moving your analysis to RDataFrame - which is the class which we recommend for a modern data analysis, in particular, defining new variables is much more straightforward. Here you can find many tutorials which should help you with RDataFrame based analysis. If you would like to generally learn a bit more about RDF and some other modern features of ROOT, used from Python, you can follow this student course while you can also watch the recording of the course.

Secondly, I can also see that you are using quite an old version of ROOT. I would also update it to the most recent version being 6.38, as this will give you access to most features, also in RDataFrame.

Cheers,

Marta

1 Like

Instead of creating branches for individual variables, you could try:
Tree_Maker::Tree_Maker(TTree *tree) { tree->Branch("Tree_Maker", this); }

This is indeed one of the core ROOT functionalities see I/O Concepts - ROOT and I/O of custom classes - ROOT

Thank you, @Wile_E_Coyote. This is what I was looking for.

I ran a few tests, and the only difference between my current method and “this” method is as follows:

In the previous method, to draw the variable for the generated root file, I used the following command

tree->Draw("A")

Now, since I am saving the class to the tree, I need to write the following

tree->Draw("Tree_Maker.A")

which is ok for me.

I am attaching the test files in case someone wants check the difference themselves.

This_mthd.cc (539 Bytes)
Norm_mthd.cc (569 Bytes)

Thank you, @mczurylo, for suggesting RDataFrame. I will surely try it at some point. My current project requires this specific version of ROOT and Ubuntu, otherwise it refuses to “make”. So I am stuck.

Thanks for referring to the detailed wiki @pcanal. I will go through it.

You can easily “extend” it (a tree with several independent “Tree_Maker” objects):

This_mthd_3_tree.cxx (1.0 KB)

1 Like