# Writing into, then drawing two-dimensional arrays from a TTree, with one dimension having variable length

As an intermediate step to creating some histograms using

getVoltsAtDigitizerCuts.C (4.6 KB)

I wrote the macro

makeVoltsAtDigitizerFile.C (6.1 KB)

to create a file from which to use TTree::Draw() from. Initially I had variables of dimensions [108][260], but it turns out that for each index along the first dimension of length NUM_DIGITIZED_CHANNELS = 108, the length along the second dimension varies in length somewhere between 248 to 252. Anything beyond a length of 252 in the second dimension isn’t filled. In the macro “makeVoltsAtDigitizerFile.C” above, is there a way to copy over variables with dimensions [108][260] to [108][fNumPoints], where for “fNumPoints” is an array of length 108 with entries equal to length in the second dimension?

I thought that maybe the following exercise could be generalized to be used for two-dimensional arrays
https://root.cern.ch/root/html/tutorials/tree/tree3.C.html
where I am intending to use “fNumPoints” like “ntrack” in the exercise. If this can’t be done, can this somehow be done with vectors, like suggested here
https://root-forum.cern.ch/t/ttree-multiple-variable-length-arrays/17466/3?
If so, what lines would I change in “makeVoltsAtDigitizerFile.C”, and to what would they be changed to?

Ultimately, the purpose of all this is to exclude empty elements along the dimension of length NUM_SAMP = 260 from being filled for histograms of variables with dimensions [108][260] in “getVoltsAtDigitizerCuts.C”, so there could be alternative methods to what is being asked about above. The crudest alternative that I can think of is using something like the following for loop:

``````for (int i = 0; i < 108; ++i) {

for (int j = 0; j < fNumPoints[i]; ++j) {

TTree -> Draw(TString::Format("variable[%d][%d]", i , j));
}
}
``````

But filling in histograms in the following way seems to defeat the utilitiy in how ROOT chooses which elements within a variable are used to fill a histogram?

_ROOT Version:6.18/02
_Platform:linux
_Compiler:linuxx8664gcc

AFAIK, the “variable size of the array” works for 1 dimensional arrays only.
The simplest solution would be to use “(maximal) fixed sizes” for 2 dimensional arrays. When filling the array, always (for every event) initialize the “unused elements” with 0 and let the default ROOT’s file compression algorithm take care of it.
Otherwise, you’d need to use something like (the performance costs would really be huge, though): `std:vector<std::vector double> >`

Thanks, Wile.

The “(maximal) fixed sizes” is how the data I’m looking at has been initially into an array of dimensions [108][260], with the second dimension of length 260 appearing to actually vary in lengths between 248 to 252. If this is the route that I will have to take, do you have a suggestion of how to use ‘TTree::Draw()’ on 2-dimensional array variables, were the second dimension varies in length? Would I be stuck doing something like the for loop I wrote out, or does ROOT afford a more concise solution?

You could try: `tree->Draw("array[][]", "array[][] != 0");`

That is a fair, but different way of handling the problem. Then should I mark the problem as solved?