Array in branch

Hi,

I’d like to store the following toy structure inside a branch (i.e. not at the root of the tree).

#define MAX_ARR_SIZE 20

typedef struct
{
	int		njets;
	float	Et[MAX_ARR_SIZE];
	float	Eta[MAX_ARR_SIZE];

} arrJet;

I used the following constructs

	arrJet	arr_jet;	// With Array
	t->Branch("njets", &arr_jet, "njets/I"); // Cannot use range from leaf inside branch.
	
	//t->Branch("jets", &arr_jet, "njets/I:Et[jets.njets]/F:Eta[jets.njets]/F"); // <--- No branch saved
	//t->Branch("jets", &arr_jet, "njets/I:Et[20]/F:Eta[20]/F"); // <-- Works for Et ; but Eta points to Et ; And takes too much space.
	t->Branch("jets", &arr_jet, "njets/I:Et[njets]/F:Eta[njets]/F"); // <-- Works for Et ; but Eta points to Et

My understanding is that the offset is not properly set for the arrays.

Is there another way to store an array of variable size inside a branch, i.e. not at the top of the thee ?

Thanks a lot,
Karolos

see example in $ROOTSYS/tutorials/tree/tree2.C

Rene

1 Like

Thanks for your reply Rene,

I was aware of this tutorial. I tried to extend it to my case without success. What I want is

tree->Draw(“jets.Et[0]”); and not tree->Draw(“Et[0]”);

The tutorial stores the arrays as branches inside the tree, not branches inside branches. How would that be possible ?

I see that the case where I have basic variables (i.e. not arrays) works fine, even if the sequence is ended by an array. But when I put anything after the array in my branch descriptor string, it does point to the beginning of the variable size array.

Karolos

see example in file below (use a version >=5.26)
and do

root > .x t1.C+
Rene

//file t1.C

[code]#include “TFile.h”
#include “TTree.h”
#define MAX_ARR_SIZE 20

typedef struct
{
int njets;
float Et[MAX_ARR_SIZE];
float Eta[MAX_ARR_SIZE];

} arrJet;
void t1() {
TFile *f = new TFile(“t1.root”,“recreate”);
TTree *T = new TTree(“T”,“test”);
arrJet arr_jet; // With Array
T->Branch(“njets”, &arr_jet);
T->Print();
T->Write();
delete f;
}
[/code]

Thanks Rene for the continuous help.

However I’d like now to have VARIABLE size arrays. That’s were I cannot get it to work. Sorry if my previous posts didn’t make that clear.

Karolos

use this variant (more details in Users Guide)

Rene

//file t1.C

[code]#include “TFile.h”
#include “TTree.h”

class arrJet
{
int njets;
float *Et; //[njets]
float *Eta; //[njets]

};
void t1() {
TFile *f = new TFile(“t1.root”,“recreate”);
TTree *T = new TTree(“T”,“test”);
arrJet arr_jet; // With Array
T->Branch(“njets”, &arr_jet); // Cannot use range from leaf inside branch.
T->Print();
T->Write();
delete f;
}[/code]

Thanks Rene.

I was unable to get your example run but found the solution to my problem. The idea is to use TLeaf::SetAddress.

Here’s more detail for further reference.


	TBranch* br = t->Branch("jets", &arr_jet, "njets/I:Et[njets]/F:Eta[njets]/F");

	br->GetLeaf("jetEt")->SetAddress(arr_jet.Et); // <-- Not really needed for the first array
	br->GetLeaf("jetEta")->SetAddress(arr_jet.Eta);

Thanks a lot.

Karolos

of course my example runs. It means that you use a very old version.
The way you do it is a can of worms. It works by chance because the elements have the same basic length of 4 bytes each.

Rene