Multidimensional data in TTree::GetUserInfo


Is there a way to store simple multidimensional data like int a[10][10][10][10] in TTree::GetUserInfo() without encapsulating it in custom classes?

I simply would like to add some simple multidimensional array that is common for all TTree entries and be able to read it without needing to distribute dictionaries with it.


in this case you could store it as an array of 10^4 ints and then cast it back to the most convenient form as the size would be the same and the data would be contiguous in memory.


Thanks, I hoped that there is a way to store simple array types in GetUserInfo as it is possible inside the TTree itself…

I tried doing a similar thing but instead of the UserInfo mechanism, I just directly wrote objects into the TFile that stored the tree. I could then recover the object by getting it by name and re-casting the TObject * to the original type.

In my case I needed 1D arrays, so I wrote my own “NamedArray” class that inherits from TObject and TNamed. You can see it here:

Perhaps something similar can be done with a ROOT container for your case. Is there a standard ROOT multidimensional container (other that TTree?).


Thanks for the reply. Unfortunately it seems there is no ROOT container above 2D (well, one could make a TList of TLists of TLists… but it does not seem to be anything easy to use), so it again comes to writing own class and distributing dictionary with data, which I need to avoid.


I think the way out is rather straightforward.
If the type you are considering is an array (std::vector) of int (or double, float, …) and has a fixed size you can save it w/o additional dictionaries in a tree or a rootfile.
The way in which you access it (e.g. myvec[1][3][0][23]) is decoupled from the way you store it. Indeed such a multi-index entity is represented in memory as a contiguous block of data.
I hope this helps.


And how do you cast 1D array to a multidimensional array not knowing its dimensions at the compile time?

Multidimensional vectors in root require, unfortunately, dictionaries.

You started mentioning a “data structure” like a[10][10][10][10]. Since this assumes you know the size at compile time, I assumed so. W/o casting you can always calculate the right index to access the array element.
Btw, besides needing dictionaries, I would strongly discourage the usage of vector<vector<…>> like containers as they can be very expensive at runtime (allocations) and at I/O time.


Well, I don’t know the dimensions at compile time, since they may change from experiment to experiment. Using 1D addressing in 4D case is pain. Especially that the tree is supposed to keep a data structure that is the same as physical/electronics structure of the experiment.

I’ve managed to make it working with the tree itself (although with pain, because ROOT does not support writing multidimensional data from pointer to TTree, which makes it harder to use any arrays with dimensions not known at the compile time), but it seems that GetUserInfo() does not support as much data as the TTree does. To summarize: I understand that one cannot associate a TTree with a simple multidimensional data in a multidimensional form without using dictionaries. Is there a chance for implementing it in the future? It seems basic and would make TTree::GetUserInfo() more compatible with the TTree contents.