Multi-dimensional arrays in TTree

Dear all

I am using ROOT 6.10/04 on CentOS 7 and I discovered recently
that TTree->Draw() and TTree->Scan() commands
do not show correctly elements of 6-dimensional array.

In TTree I have

*............................................................................*
*Br   30 :Ratio     : signal_cor[10][2][4][64][48][2]/F                      *
*Entries :        1 : Total  Size=    1966688 bytes  File Size = 898799 *
*Baskets :        1 : Basket Size=      32000 bytes  Compression= 2.19     *

If I do simple Scan() I see elements of the array,
but actually only first half is printed

root [2] h3000->Scan("signal_cor")
***********************************
*    Row   * Instance * signal_co *
***********************************
*        0 *        0 * 0.1497807 *
*        0 *        1 *         0 *
*        0 *        2 * 0.4020577 *
*        0 *        3 *         0 *
*        0 *        4 * 0.1978682 *
*        0 *        5 *         0 *
*        0 *        6 * 0.3655157 *
<skip>
*        0 *   245752 *         0 *
*        0 *   245753 *         0 *
*        0 *   245754 *         0 *
*        0 *   245755 *         0 *
*        0 *   245756 *         0 *
*        0 *   245757 *         0 *
*        0 *   245758 *         0 *
*        0 *   245759 *         0 *
***********************************
(Long64_t) 245760

If I try to access first two elements, changing last index
I see the same value, as if 6th index doesn’t exist:

root [3] h3000->Scan("signal_cor[0][0][0][0][0][0]:signal_cor[0][0][0][0][0][1]")
************************************
*    Row   * signal_co * signal_co *
************************************
*        0 * 0.1497807 * 0.1497807 *
************************************

and in order to access second element in array I need to change 5th index instead:

root [4] h3000->Scan("signal_cor[0][0][0][0][0]:signal_cor[0][0][0][0][1]:signal_cor[0][0][0][0][2]:signal_cor[0][0][0][0][3]")
************************************************************
*    Row   * signal_co * signal_co * signal_co * signal_co *
************************************************************
*        0 * 0.1497807 *         0 * 0.4020577 *         0 *
************************************************************

Is it known limitation of ROOT or it’s actually a bug ?
And why ROOT silently gives wrong value instead of giving some error message,
like error message about array index outside limits:

root [5] h3000->Scan("signal_cor[10][0][0][0][0][0]")
Error in <TTreeFormula::TTreeFormula>: Index 10 for dimension #1 in signal_cor[10][0][0][0][0][0] is too high (max is 9)

With best regards
Alexander

There is currently a limit in the number of dimensions that a C-style vector can have in ROOT. Unfortunately, that number is five, just one under what you have. This was due to a limitation in the old cint interpreter, so we may be able to fix it now by increasing that maximum number in ROOT. For the moment, I do not know what you could do to workaround the problem. I will ask others in the team.

short of fixing ROOT/CLing, an “easy” way would be to declare a big enough 1D array of the correct size (ie: dim = dim1*dim2*dim3* ...*dim6) and then carve it up how you wish.
that’s what the C compiler does when you say int64_t arr[10][2];, memory-wise, it is the same than having int64_t arr[20];
you’ll “just” have to do the indexing translation manually.

Hello,
Yes, I’ve figured out that I need to do remapping.
The only small problem is that I can’t look at second half of the array interactively in Scan() and Draw() commands if I want to check something quickly (since last dimension [2] is ignored)
It would be nice to have possibility to make such remapping from multi-dim to one-dim array directly at ROOT prompt, assuming that user calculates correct index himself. For example, to have double [[ ]] around index

special syntax is nice except that it’s special syntax, and thus has to be looked up, learned and taught (and ROOT’s interpreter has a long story of being almost like C++ except when it’s not.)

what’s wrong with introducing an nd_index function that does the index calculation?
it’s explicit, portable and doesn’t require learning+maintaining something new.

Sure, I am not against new function or any other relatively simple way to access all elements of the array at the ROOT prompt.

Actually, what I meant was that you can already define such a function and call it from your Scan or Draw call.
no modification of ROOT required.

I guess it should be a function of 7 parameters, similar to this:

float my_function(const float *array, int i0, int i1, int i2, int i3, int i4, int i5) {

int maxdim[] = {10,2,4,64,48,2};

int ind = i5 + maxdim[5] * (i4 + maxdim[4] * (i3 + maxdim[3] * (i2 + maxdim[2] * (i1 + maxdim[1] * i0))));

return array[ind];
}

But could you please explain how to define new function which can be usable in Draw()
I didn’t find anything in ROOT tutorials

Or let me ask slightly different question
How can I access elements of multi-dim array in TTree as if it is one-dim array ?
Is there any trick ?

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