TTree with multi-dimensional leaves

PzoGainsTmp.root (8.13 KB)Hi,

I have a simple root file (attached) that has a couple 2d arrays for leaves. I seem to not be able to access these leaves properly via the code attached here. I must be doing something really wrong, because I can not seem to even access the normal leaf (that is not an array). However, if I do a TTree::Scan() or TTRee::Print(), I see all the information (I have commented out these two lines).

What am I doing so so wrong here?

code to read the tree: run in root as .x NtupleWithTTreeIndex.C++

#include<iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <cmath>
#include <vector>
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <stdio.h>

#include "TSystem.h"
#include <TTree.h>
#include "TFile.h"
#include "TChain.h"
#include "TROOT.h"

using namespace std;

void NtupleWithTTreeIndex();


void NtupleWithTTreeIndex()
{

  TFile *f = new TFile("PzoGainsTmp.root");
  TTree *T1  = (TTree*)f->Get("SomeGains");

  Int_t RunIndexGains2; //run index
  Int_t prodnumGains2[32]; //detector number 
  Double_t gainA2[32][9];
  Double_t gainPI2[32][9];

  T1->SetBranchAddress("RunIndexGains",&RunIndexGains2);
  T1->SetBranchAddress("prodnumGains[32]",&prodnumGains2);
  T1->SetBranchAddress("AGain[32][9]",&gainA2);
  T1->SetBranchAddress("PzoIndexGains[32][9]",&gainPI2);
  
  //T1->Print();
  //T1->Scan("RunIndexGains:prodnumGains[3]");

   Int_t nentries = (Int_t)T1->GetEntries();
   cout<<"entries "<<nentries<<endl;

   for(Int_t gj=0; gj<nentries; gj++)
     {
       Int_t gbytes = T1->GetEntry(gj);
       if (gbytes == 0) continue;
       T1->GetEntry(gj);
       cout<<RunIndexGains2<<"\t"<<prodnumGains2[3]<<endl;
     }

  cout<<"done"<<endl;
}

and the root file PzoGainsTmp.root is attached here.

And if you want to see the code I used to make this root file, it is here:

using namespace std;

void NtupleWithTTreeIndexMake();

class SomeGains : public TObject
{
 public:

  Int_t RunIndexGains; //run index

  Int_t prodnumGains[32]; //detector number 

  Double_t AGains[32][9]; //Amplitude gains per det per pzo per period, calculated with unsaturated signals.
  Int_t PzoIndexGains[32][9]; //index of pzo

  SomeGains():
    RunIndexGains(0)
      
  {
   
    for(Int_t ii=0; ii<32; ++ii)
      {
	prodnumGains[ii] = 0.;

	for(Int_t jj=0; jj<9; ++jj)
	  {
	    AGains[ii][jj] = 0.;
	    PzoIndexGains[ii][jj] = 0.;
	  }
      }
  
  }

  ClassDef (SomeGains,1);
  
};

void NtupleWithTTreeIndexMake()
{

  TFile *PzoGains;
  PzoGains = new TFile ("PzoGainsTmp.root","RECREATE");

  TTree *treeg;
  treeg = new TTree("SomeGains","Pzo Gains");

  treeg->SetDirectory(PzoGains);

  SomeGains *gainsome = new SomeGains;
  //tree->SetCacheSize(0);

  treeg->Branch("GainsSome",&gainsome);

  for(Int_t fii=0; fii<10; fii++)
    {
      gainsome->RunIndexGains = fii+1600;

      for (Int_t dii= 0; dii<32; dii++){
	gainsome->prodnumGains[dii] = dii+30;

	for (Int_t pzi= 0; pzi<9; pzi++){
	  gainsome->PzoIndexGains[dii][pzi] = pzi;
	  gainsome->AGains[dii][pzi] = Double_t(fii+dii+pzi);
	}
      }
      treeg->Fill();
    }
  treeg->SetDirectory(PzoGains);
  treeg->BuildIndex("RunIndexGains","prodnumGains");

  PzoGains->Write();
  PzoGains->Close();

}

Thanks a lot!

  • Sujeewa

Hi,

The best is to use your object when reading too:SomeGains *gainsome = 0; tree->SetBranchAddress("GainsSome",&gainsome);Alternatively add T1->SetMakeClass(1) to your original code to tell the TTree that you want the object to be decomposed into its elementary parts.

Cheers,
Philippe.

Hi Philippe,

Thanks a lot! The SetMakeClass(1); worked.

But now, my 2-d arrays are giving me garbage. So I am thinking I am not properly SetBranchAddress-ing for them. How does one SetBranchAddress for a 2d array? I would imagine

T1->SetBranchAddress(“AGain”,&gainA2);

should work, where AGain is a 2d array of32*9 from the tree and Double_t gainA2[32][9]; (in the code I posted earlier).

But, it didn’t like it, complaining that AGain does not exist. So I switched to what I have in the code I posted earlier:
T1->SetBranchAddress(“AGain[32][9]”,&gainA2);

but this gives random numbers for gaisA2[i][j].

Thanks again!

  • Sujeewa

T1->SetBranchAddress("AGains[32][9]",gainA2);should work (see the result of SomeGains->MakeSelector(“sel01”):wink:

Cheers,
Philippe.

Aha… I had a typo, I wrote AGain instead of AGains. Thanks a lot Philippe!

  • Sujeewa