In order to read sub-parts of a TClonesArray (you case) you must set the TTree in MakeClass mode and set the address of both the index and the value:[code] int len;
float met[10];
met[0]=0;
TTree* t1 = (TTree*) f1->Get(“Analysis”);
TBranch *b_met = t1->GetBranch(“ETmis.ET”);
t1->SetMakeClass(1); // For the proper setup.
t1->SetBranchAddress(“ETmis”,&len);
b_met->SetAddress(&met);[/code]
The alternative is to ‘get’ the address rather than setting them.
I am having precisely the same issue. I followed the instructions of Philippe, and now i have a
segmentation fault error.
My Tree and Branch structure is the same but with different names. The code below illustrates this:
void tree4w()
{
int len;
Float_t PT;
// call in root file and branches of interest
TFile *f = new TFile("out2.root");
TTree *t = (TTree*)f->Get("Delphes");
TBranch *j = t->GetBranch("GenJet.PT");
t->SetMakeClass(1);
t->SetBranchAddress("GenJet",&len);
j->SetAddress(&PT);
// i would like to print out the first 10 entries....
for (Int_t i=0; i<10; i++)
{
j->GetEntry(i);
cout << " PT " << PT << endl;
}
}
The output is:
It does print out the 10 values, but always there is some segmentation fault. Any help is greatly appreciated…
Thanks,
C
[quote]Warning in TClass::TClass: no dictionary for class GenParticle is available
Warning in TClass::TClass: no dictionary for class SortableObject is available
Warning in TClass::TClass: no dictionary for class Tower is available
Warning in TClass::TClass: no dictionary for class Muon is available
Warning in TClass::TClass: no dictionary for class Jet is available
Warning in TClass::TClass: no dictionary for class Electron is available
Warning in TClass::TClass: no dictionary for class Photon is available
Warning in TClass::TClass: no dictionary for class MissingET is available
Warning in TClass::TClass: no dictionary for class ScalarHT is available
PT 83.2372
PT 89.9823
PT 42.5891
PT 25.2559
PT 31.0609
PT 28.6984
PT 0
PT 0
PT 0
PT 0
[/quote]
and i know there are over 16000 entries in this Branch…
did you have this issue when you implemented Philippe’s solution?
Thanks for your help!
C
I am encountering a similar problem, I am using the following code to read a TVector3 from a root file but it always get crashed, any idea?
Code:
void test() {
int len;
TVector3 x[9];
gROOT->Reset();
TFile *f = new TFile("test.root");
TTree *t1 = (TTree*)f->Get("GigaTracker");
TBranch *branch1 = t1->GetBranch("fCandidates.fPosition[3]");
cout << branch1->Print() << endl;
t1->SetMakeClass(1);
t1->SetBranchAddress("fCandidates.fPosition[3]",&len);
branch1->SetAddress(&x);
for (Int_t i = 0; i<9; i++){
branch1->GetEntry(i); // crash at this line
//cout << "x" << x << endl;
}
}
Running log:
[code][root@ppepc176 rootreco2]# root -l test.C
root [0]
Processing test.C…
Warning in TClass::TClass: no dictionary for class TDetectorVEvent is available
Warning in TClass::TClass: no dictionary for class TVEvent is available
.
.
.
Warning in TClass::TClass: no dictionary for class TSACDigi is available
*Br 0 :fCandidates.fPosition[3] : TVector3 fPosition[fCandidates_] *
*Entries : 5000 : Total Size= 616133 bytes File Size = 155241 *
*Baskets : 20 : Basket Size= 32000 bytes Compression= 3.96 * …
0
*** Break *** segmentation violation
===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================[/code]
The structure of the root file is show in the attached plot.
gROOT->Reset();Never call gROOT->Reset() inside a function, it’s purpose is to wipe the slate clean and thus is/should remove the function you are executing …
TBranch *branch1 = t1->GetBranch("fCandidates.fPosition[3]");
t1->SetBranchAddress("fCandidates.fPosition[3]",&len);
branch1->SetAddress(&x);
What is the meaning/purpose of setting the address of the same branch twice to different location?
int len;
t1->SetBranchAddress("fCandidates.fPosition[3]",&len);
Currently SetBranchAddress does not cross-check the type being passed … here you pass an ‘int’ (only 4 bytes) to store 3 TVector3 objects (40*3=120 bytes!)
t1->SetMakeClass(1);SetMakeClass allow the reading of individual data member by setting their address directly … but it also completely disable the ability to read the data as objects (as is your case).
One recommendation would be to upgrade to the current version of the master and to use the new implementation of TTree::MakeSelector to generate code using the TTreeReader that will make what you need very easy:t1->MakeSelector("selector","fCandidates.fPosition");
Cheers,
Philippe.
PS. The following ‘might’ work: TVector3 x[9];
TFile *f = new TFile("test.root");
TTree *t1 = nullptr;
f->GetObject("GigaTracker",t1);
TBranch *branch1 = t1->GetBranch("fCandidates.fPosition[3]");
cout << branch1->Print() << endl;
t1->GetEntry(0); // for the setting of the address
branch1->SetAddress(&x); // over-ride the address setting.
// Alternatively:
// TVector3 *ptr = (TVector3*)branch1->GetAddress();
for (Int_t i = 0; i<9; i++){
branch1->GetEntry(i); // crash at this line
//cout << "x" << x << endl;
}
Thanks for the clarification, the following code does not crash but the readout value of ptr->Px() is always 6.9195e-310, which is not correct, any idea?
void test() {
TFile *f = new TFile("test.root");
TTree *t1 ;
f->GetObject("GigaTracker",t1);
TBranch *branch1 = t1->GetBranch("fCandidates.fPosition[3]");
branch1->Print() ;
t1->GetEntry(0);
TVector3 *ptr = (TVector3*)branch1->GetAddress();
for (Int_t i = 0; i<100000; i++){
branch1->GetEntry(i); // crash at this line
cout << "x" << ptr->Px() << endl;
}
}
I would assume that it’s a TVector** - the address of the array.
TVector3 **ptr = (TVector3**)branch1->GetAddress();
for (Int_t i = 0; i<100000; i++){
branch1->GetEntry(i); // crash at this line
cout << "x" << ptr[0]->Px() << endl;
...