Uniform ways of adding branches in pyROOT

Hello,

When I want to add an int or an array of ints to a branch in a TTree in pyROOT I do:
t.Branch("a", a, "a[2]/I")
However, when I want to add a vector of something, I do:
t.Branch("c", "std::vector<string>", get_var)

In one case the type is the 3rd argument, in the second case it is the second argument. Can it be uniformised? Maybe there are basic classes in ROOT for basic types that could be add as a second parameter?

Otherwise in automatic TTree structure generation, one has to check if he is adding a basic type or an std type and on that base a syntax for the Branch() call, which is far from pretty :slight_smile:

Hello,

If this helps a bit, for the vector case, you can also do:

t.Branch("c", get_var)

and with this the second argument is the object itself, instead of the type (which you can omit). Still for the array case you need to provide the third argument with the type and size.

Anyway in PyROOT we rely on the overloads that are defined in C++ for TTree::Branch. On top of that, there could be a pythonization that checks that if the parameter is a Python array.array or numpy array we generate the third argument from the size and type, but this is not provided at the moment. Contributions in the form of new pythonizations are of course welcome :slight_smile:

Thanks, it works, but unfortunately does not help. The syntax still has to be different (although easier) when using vector and when using basic types, so I need an “if” that will check what type of branch I am creating.
I understand that these are just python wrappers for C++ functions, but, in general, the problem is in C++. It would be nice to have a consistent method Branch(), where ordering of arguments would be the same. Maybe you could consider adding such a method version in the future? Probably 1 or 2 lines of code…

For python bindings, I’ll seriously consider contributing. It would be nice to have automatic recognition of array types, and perhaps even generation of a branch full of leaves depending on the types inside a numpy array :slight_smile:

Thanks @LeWhoo ! Looking forward to your contribution.

As for the overloads in C++ for Branch, perhaps @pcanal can comment.

If you have a PR that is backward compatible, I will take it.

In the meantime in C++, you don’t need the 2nd arguments (in either case) … except for C style array where we can’t auto-detect the size.
I.e.

int i;
float f;
std::vector<int> vi;
tree->Branch("i", &i);
tree->Branch("f", &f);
tree->Branch("vi", &vi);
/// but
int ar[3];
tree->Branch("ar", ar, "ar[3]/I");
/// But then again you could use:
std::array<3> array3;
tree->Branch("array", &array3);

I see. So it is a problem of the python bindings that they do not accept the Branch(name, reference) call for simple types…

Hi,

For simple types, yes, we need the extra string with the type in Python because, if you pass an array of one position as object, we can’t know if you want the branch to be e.g. a float array of one position or a float.

This would be solved e.g. by allowing ctypes types to be passed instead of one-position arrays, but this needs a pythonization that is currently not implemented.

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