Reading TTree variables into class

I have a root tree, containing the kinematic variables of a particle ( _pt, _eta,…), and every entry in the tree has multiple particles, so every entry has an arrays of kinematic variables corresponding to every particle. Now I have defined a particle class that contains among other things the kinematic variables as its members. Now I wonder if I have an array of such “particle” objects if it is possible to read the info from the TTree directly into the particle objects.

To better illustrate what I am trying to do:
Normally I would read the variable “_pt” out of my tree using the following code:

TTree *tree;
double _pt[10];
TBranch *b__pt;
tree->SetBranchAddress("_pt", _pt, &b__pt);

However now Assume I have the class:

class particle{
		double pt;

And an array of such particles :

 particle particleArray[10];

Would it be possible to use “->SetBranchAddress” to directly read the info from my tree into the correct “particle” object?
Thanks in advance for the help!

Hi willem,
yes that is possible, you just have to pass the address of particle's data member to SetBranchAddress.
A double variable is a double variable, even if it’s part of a class.

From a design perspective, on the other hand, it is generally not considered good practice to have public data members. Consider whether this might be premature optimization: I am pretty sure that you wouldn’t even notice the difference if you added one or two extra copies of doubles (one assembly instruction) versus the time it takes to read, deserialize, decompress and return that double from your data-set on disk (orders of magnitude more instructions).

Hello Enrico,
Thanks for your reply! So how would my SetBranchAddress command look to achieve this? Should it be something like

tree->SetBranchAddress("_pt", &(particleArray->pt), &b__pt) 

? I was a bit confused how to do this because of the fact that I have an array of particles and I am not sure whether every “_pt” ends up with the correct entry in the particle array.

The fact that it is preferable for the data not to be public leads me to the question whether it is possible, having a function:


(that as you guessed, sets the pt), and somehow giving this to the branchadress statement?

Upon reading you question again I see _pt is an array of doubles. This means you have to pass an array of doubles to SetBranchAddress. If it was just one double, you could have done something like

particle p;
t.SetBranchAddress("pt", &;

or, slightly better,

particle p;
t.SetBranchAddress("pt", &p.GetPt());

where GetPt is defined as in:

class Particle {
  double pt;
   double &GetPt() { return pt; } // return a reference to the actual member variable

What I would suggest is that you call SetBranchAddress passing an array of doubles, and then copy them in the array of particles like this:

particles p[10];
double pts[10];
t.SetBranchAddress("_pt", pts);
for(int i = 0; i < 10; ++i)

I know it’s more verbose and also less efficient, but if it is going to be part of a larger application it will be much easier to debug, understand, refactor.

I cannot say what is the right design for your particular application. Good guidelines are that premature optimization does more harm than good (when your application works with no hiccups, then you go in and optimize the hotspots if you need to), and encapsulation (regulating access to data through classes’ methods) helps writing correct code that is easier to understand and refactor. Good luck :slight_smile:

the answer to your original question is then no, there is no easy way to tell TTree to fill the pt member variable of 10 different particle objects at the same time. The reason is that an array of double is contiguous in memory (the bits of all doubles come one after another in RAM) while there is no way to get 10 member variables of different objects to be contiguous in memory – and TTree rely on the fact that the bits it will have to fill with your pts are all contiguous, i.e. are part of the same array.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.