Split object with multidim array, TTree::Draw()

Hi,

Sorry for the truncated title.

I have a class that is being stored in a TTree with splitting enabled. The class has some multidimensional arrays of primitive types (int/double/bool) with one fixed and one dynamic dimension.
(like phi = new double[ncam][15] where ncam is determined at runtime)

I can store the arrays as collapsed 1-d array like

double * phi // [ ncam_times_15] 

but then I do not get the desired behavior for TTree::Draw(phi[cam]) which is very useful in interactive mode.

I tried declaring the variable as

double (*phi)[15];  // [ncam] 

which compiles fine, but this leads to segmentation faults in the Streamer so something isn’t working right.

If I enable debug mode, I see output like:

and

which looks like something has definitely gone wrong…

I also tried various tricks using typedefs of double[15] but those didn’t seem to work either (rootcint said something about manual intervention being required).

Is there a proper way to get multidimensional arrays to cooperate with Draw?

[quote]Is there a proper way to get multidimensional arrays to cooperate with Draw?[/quote]The easiest way is to use a vector<vector >

Cheers,
Philippe.

I’m now having trouble with streamers for the vectors.

Basically the problem is I want to populate these vectors from a TTree and then store them in an object.

The obvious (to me) way to do that is to have something like:

class MyObject : TObject
{
  ... 
   private:
      vector<vector<double> > * phi; 
   ... 
}; 

and something like

tree->SetBranchAddress("phi",&phi); 

to write to it.

However, it looks like there is a problem generating the streamer (the generated code does not compile). Looking at the generated code, it seems like it does something like

*phi = new vector<vector<double> >;

instead of the compilable

phi = new vector<vector<double> >;

This works fine if I don’t use pointers in my object but then I have to perform some gymnastics for setting the branch address on the tree.

[quote]However, it looks like there is a problem generating the streamer (the generated code does not compile). Looking at the generated code, it seems like it does something like [/quote]Most likely you can solve the problem by using the new io streamer by using#pragma link C++ class MyObject+;(note the trailing +).

Cheers,
Philippe.

Thank you. One more question (I think).

I got it to work fine for two dimensional stuff, but if I try it with a three dimensional field (vector<vector<vector > > ) I get

when I try to do something like tree()->Draw(“field[0][0]”)

Is it possible to generate a dictionary or something to make it work or is it limited to two dimensions?

[quote]Is it possible to generate a dictionary or something to make it work or is it limited to two dimensions?[/quote]The formula syntax TTree::Draw only supports 2 variables dimensions. To handle you case you will need to do the looping explicitly, for example by using a TTree::Draw ‘script’:

// File mydraw.C double mydraw() { long size = field[0][0].size(); for(long i = 1; i < size; ++i) { htemp->Fill(field[0][0][i]); } if (size>0) return field[0][0][0]; return 0; }and use:tree()->Draw("mydraw.C");

Cheers,
Philippe.