TTree 2D array

Hello,

I am trying to save a 2D array data[2][20] in a TTree t. When I do

everything is fine.

But I would like to store arrays that can have variable size. So when I do

t->Branch("n",&n,"n/I");
t->Branch("data",data,"data[2][n]/b");

I don’t get the data that I expect.

I presume that a variable-size array is allowed, right? I appreciate some help to solve this problem.

Examples of writing and reading the data are given below.

Cheers,
Roberval

WriteData.C

void WriteData()
{
   unsigned char data[2][20];
   int nbytes = 20;
   int n;
   
   TFile f("tree.root", "recreate");
   
   TTree *t = new TTree("T","tree");
         
   t->Branch("n",&n,"n/I");
   t->Branch("data",data,"data[2][20]/b");

   // Emulate the ADC (dummy data)
   unsigned char dummy_data[2][20];
   
   for ( int i = 0 ; i < nbytes ; ++i )
   {
      dummy_data[0][i] = 0x89+i;
      dummy_data[1][i] = 0x8D+i;
   }

   // Copy dummy data in the ADC format, 32-bit words
   // adcData is the block of data readout from ADC 
   // [board][20bytes*8channels]; int has 4 bytes
   int adcData[2][40];
   for ( int i = 0 ; i < 8 ; ++i ) // loop over channels
   {  
      memcpy(&adcData[0][i*(nbytes/4)],&dummy_data[0][0],nbytes);
      memcpy(&adcData[1][i*(nbytes/4)],&dummy_data[1][0],nbytes);
   }
   
   
   // Loop over the 8 channels of an ADC
   // Store channel data as an entry in the ntuple
   for ( int i = 0 ; i < 8 ; ++i ) 
   {  
      memcpy(&data[0][0],&adcData[0][i*nbytes/4],nbytes);
      memcpy(&data[1][0],&adcData[1][i*nbytes/4],nbytes);
      n = nbytes;
      t -> Fill();
   }
   t -> Write();
}

ReadData.C

void ReadData()
{
   unsigned char data[2][20];
   int n;

   
   TFile f("tree.root", "old");
   TTree *t = (TTree*) f.Get("T");
         
   t->SetBranchAddress("n",&n);
   t->SetBranchAddress("data",data);
   
   int x[100], y[100];

   // Plot for channel 7 of board 1
   int channel = 7;
   t -> GetEntry(channel);
   for ( int i = 0 ; i < n ; ++i)
   {
      x[i] = int(i);
      y[i] = int(data[1][i]);
   } 
   TGraph * gr = new TGraph(n,x,y);
   gr -> Draw("AC*");
   

 }
1 Like

Hi,

[quote]I presume that a variable-size array is allowed, right? [/quote]Yes, but only with one dimension. The two dimensions case with one variable is not official supported:

[quote] // Arrays of values are supported with the following syntax:
// If leaf name has the form var[nelem], where nelem is alphanumeric, then
// if nelem is a leaf name, it is used as the variable size of the array,
// otherwise return 0.
// If leaf name has the form var[nelem], where nelem is a non-negative integer, then
// it is used as the fixed size of the array.
// If leaf name has the form of a multi-dimensional array (e.g. var[nelem][nelem2])
// where nelem and nelem2 are non-negative integer) then
// it is used as a 2 dimensional array of fixed size.
// Any of other form is not supported.[/quote]but ‘might’ work with “data[n][2]/b”

Cheers,
Philippe.

Dear Philippe,

Thank you for the prompt reply. Indeed I have used your suggestion "‘might’ work with “data[n][2]/b” in the past in another case and thought it would work the other way around.

Cheers,
Roberval