Big problem reading TTree with Branch and Leaves

Hi, working with a tree that have a branch and within the branch same leaves. The code is:

#include <TTree>
#include <TLeaf>
#include <TBranch>
#include <TRandom>
#include <TFile>


Int_t nels;
Double_t val1[100];
Double_t val2[100];

void complextree() {
  TFile *file = new TFile("complextree.root","recreate");
  TTree *mytree = new TTree("mytree","My data tree");
  mytree->Branch("DATA",&nels,"nels/I:val1[nels]/D:val2[nels]/D");
  /*
  TBranch *branch = mytree->GetBranch("DATA");
  branch->GetLeaf("val2")->SetAddress(val2);
  branch->GetLeaf("val1")->SetAddress(val1);
  branch->GetLeaf("nels")->SetAddress(&nels);
  */
  for (Int_t i=0;i<1e4>Poisson(10);
    for (Int_t j=0;j<nels>Uniform(0,1);
      val2[j] = gRandom->Gaus();
    }
    mytree->Fill();
  }
  mytree->Write();
  file->Close();
}

After this I open the file and try to read the data.

All work well if I use the methods Draw() or Scan() but if I use the code created by MakeClass() or MakeSelector() to make a loop in the TTree the values contained in the variables in DATA.val1[] and DATA.val2[] don’t make sense (values as 10^200 or nan appear).

To increase the mystery if I open the ROOT file and look in the TTree with Scan() have good values, but if I try to use the code of the TSelector after this attempt the value in the TTree changes.

What is the problem?

I’m using ROOT 5.10.00 but the same problem exist with 5.08.

Thank you in advence, Guido

Change the declaration of your branches to

mytree->Branch("nels",&nels,"nels/I"); mytree->Branch("val1",val1,"val1[nels]/D"); mytree->Branch("val2",val2,"val2[nels]/D");
You cannot mix data types of different sizes in the same branch

Rene

[quote]Change the declaration of your branches to

mytree->Branch("nels",&nels,"nels/I"); mytree->Branch("val1",val1,"val1[nels]/D"); mytree->Branch("val2",val2,"val2[nels]/D");
You cannot mix data types of different sizes in the same branch

Rene[/quote]

Uhm… ok, I know that this change in the code work.

Now I’m trying to explain better the question: I want to create a TTree with various branches, like TTree created by analysis program like in CDF software or ATLAS but I think in ALICE or LHCb too.

Usually in a TTree you shall find various branches, with variables of different type, like my example int and double or float values. In the ROOT documentation exist an example to create a branch from a c-structure but this example don’t work when a member of the structure is an array.

In any case a question is still open: why reading the TTree with Scan() I obtain the right values while when I try to read the tree from a class I corrupt the TTree? this seems a bug.

See an example of a C struct with arrays (including variable length arrays)
in tutorial tree2.C. However the best approach is to use a class instead of a struct and let ROOT split automatically (ie create the sub-branches) automatically for you.

Concerning your problem when reading, you are probably doing something wrong. Without a concrete piece of code that I can execute, I cannot tell you more.

Rene

I tried the example the you cite, but this continue to create a tree with various branches and in any branch a variable, scalar or array.

I want to do something of different: a tree with some branch that contain a group of variables, i.e. a branch for MC truth and another for recostruction data.

The code the I posted in the begin of the thread seems work: it create a tree with a branch and within the branch 3 variables; the branch created work using simple mehods like Scan() and Draw() or obtain address of the leaf.

But the problem is that the peoples the want to use this tree usually read the data using code automatically created from ROOT by MakeClass() method, and the code created don’t work.

I tried using a class but opening the file ROOT print a warning messages so I think must be another method.

thats all.

thanks, guido

We need something more concrete to progress. Send teh shortest possible RUNNING script reproducing your problem.

Rene

In attachment “complextree.C” create the TTree and save it in a file, complextree.root.

If I read the file with the TBrowser or with the Scan method the values contained in in val1 e val2 are valid.

But if I use the class mytree, in mytree.{h,C}, created with MakeClass() the value in the TTree are wrong.

I hope that this codes are usefull.

many thanks, guido
mytree.h (3.45 KB)
mytree2.C (1.42 KB)
complextree.C (967 Bytes)

I already told you that thw way you create your branches in complextree is wrong. Use the correct and simpler version below.

Rene

[code]void complextree() {
TFile *file = new TFile(“complextree.root”,“recreate”);
TTree *mytree = new TTree(“mytree”,“My data tree”);
Event *myevent = new Event;

mytree->Branch(“nels”,0,“nels/I”);
mytree->Branch(“val1”,0,“val1[nels]/D”);
mytree->Branch(“val2”,0,“val2[nels]/D”);

Int_t nevts=10;
for (Int_t i=0;inels = gRandom->Poisson(10);
for (Int_t j=0;jnels&&j<100>val1[j] = gRandom->Uniform(0,1);
myevent->val2[j] = gRandom->Gaus();
}
mytree->Fill();
}

mytree->Write();
mytree->Print();
delete file;
}
[/code]

Ok, problably I will follow your example, but I remain courios how is possible the exist TTree showed by TBrowser like the example in attachment:

  • you shall see a list of leaf, of dirrent type, contained in a branch (DFINDER).

How can create a TTree like this?

In this discussion I understand that this is impossible.

many thanks, guido


In this discussion I understand that this is impossible. It is not impossible but it is very hard to do (a wrapper tool named HepTuple was somewhat sucessfully in doing it but is no longer supported). In addition, it turns out that the result is actually inferior in term of file size and file access speed so it is not really worth it …

Cheers,
Philippe