TLorentzVector Fill Problem to a TTree or to a Histogram

Hello friends,
I am struggling for 3 days with this problem. I couldn’t find the explicit solution neither in the forum nor in the manuals and tutorials. There is no problem while I am trying to fill a histogram or a TTree with an int or double but I don’t know how to fill them with a vectors especially with a TLorentzVector in a loop. Everything is fine in the code till the filling part. Then I get;

“Error in TRint::HandleTermInput(): cling::InvalidDerefException caught: Trying to access a pointer that points to an invalid memory address.”

I don’t know is it just a simple pointer problem but I tried and couldn’t make it.

{
TFile* input = new TFile(“genie-nu_tau.root”);
TTree* t = (TTree*)input-> Get(“gst”);
t -> Print();
t->Scan(“Ei:pxi:pyi:pzi”);

t->SetBranchAddress(“Ei”, &Ei);
t->SetBranchAddress(“pxi”, &pxi);
t->SetBranchAddress(“pyi”, &pyi);
t->SetBranchAddress(“pzi”, &pzi);

Int_t nentries = (Int_t)t->GetEntries();
Double_t Ei;
Double_t pxi;
Double_t pyi;
Double_t pzi;

//construct TTree
TTree * pE = new TTree(“pE”, “lorentz tree”);

//have some variables that will be read from the TTree
int runNumber = 0, eventNumber = 0;

//branch the TTree
//arguments: branch name, address of var., var. name & type
pE->Branch(“runNumber”, &runNumber, “runNumber/I”);
pE->Branch(“eventNumber”, &eventNumber, “eventNumber/I”);
pE->Branch(“Theta”,&Theta, “Theta/D”);

pE-> Print();

//now let’s loop some events
for (Int_t i=0; i<nentries; i++) {
t->GetEntry(i);
runNumber = nentries;
TLorentzVector v1(pxi, pyi, pzi, Ei);

Double_t Phi = v1.Phi();
Double_Theta = v1.Theta();
Double_t Mag = v1.Mag();
pE->Fill();

cout << “Length of p (= Mass):” << Mag << endl;
cout << “Angle of phi (in rad):” << Phi << endl;
cout << “Angle of theta (in rad):” << Theta << endl;
}

pE->Print();

It reads couts without a problem but does not fill the values. I get same error when I tried to fill a histogram with the same way like;

//create one histogram
TH1F *hTheta = new TH1F(“hTheta”,“Theta”,1000,0,100);

for (Int_t i=0; i<nentries; i++) {
t->GetEntry(i);
runNumber = nentries;
TLorentzVector v1(pxi, pyi, pzi, Ei);

Double_t Phi = v1.Phi();
Double_t Theta = v1.Theta();
Double_t Mag = v1.Mag();
hTheta->Fill();
}

hTheta->Draw();

I saw some solutions which are using TClonesarrays or dictionary method but I couldn’t get the point.

Thank you.

The right method to use depend on the layout of your TTree (what does t->Print() shows?).
The simplest for you might be to use the TTreeReader. For some example of use of the TTreeReader for your TTree, with a recent version of ROOT, look at the file produced by t->MakeSelector(“sel”);

Cheers,
Philippe.

Thanks Philippe,
Actually things got weird. Because till yesterday I constructed my loop with two different ways and it worked like a charm. I could draw histograms (when I was trying to quit from the root it was giving Break segmentation error) or I could fill the tree with the vectors but it was returning File Size=0 at the end of the day. But it is not important now because all of them blew up! I was able to get all the values from my TLorentzVector but something happened. Let me explain.

First;
t->Print() shows:

*Br 75 :Ei : Ei[ni]/D *
*Entries : 100000 : Total Size= 4611673 bytes File Size = 4241650 *
*Baskets : 37 : Basket Size= 1044480 bytes Compression= 1.09 *

*Br 76 :pxi : pxi[ni]/D *
*Entries : 100000 : Total Size= 4611714 bytes File Size = 4243110 *
*Baskets : 37 : Basket Size= 1044480 bytes Compression= 1.09 *

*Br 77 :pyi : pyi[ni]/D *
*Entries : 100000 : Total Size= 4611714 bytes File Size = 4243350 *
*Baskets : 37 : Basket Size= 1044480 bytes Compression= 1.09 *

*Br 78 :pzi : pzi[ni]/D *
*Entries : 100000 : Total Size= 4611714 bytes File Size = 4247472 *
*Baskets : 37 : Basket Size= 1044480 bytes Compression= 1.09 *
sel.h (7.3 KB)

I uploaded sel.h file also

As I said both of these loops were giving histograms:

//create one histogram
TH1F hTheta = new TH1F(“hTheta”,“Theta”,1000,-100,100);
/

TLorentzVector *particle = new TLorentzVector();

for (Int_t i=0; i<nentries; i++) {
t->GetEntry(i);
particle->SetPxPyPzE(pxi, pyi, pzi, Ei);
cout << “Angle of theta (in rad):” << particle->Theta() << endl;
hTheta->Fill(particle->Theta());
}
hTheta->Draw();

and:

TClonesArray *pTracks = new TClonesArray(“TLorentzVector”);

//now let’s loop some events
for (Long64_t i=0; i<nentries; i++) {
t->GetEntry(i);
ROOT::Math::PxPyPzEVector v1(pxi, pyi, pzi, Ei);
new((*pTracks)[i]) TLorentzVector(v1.X(), v1.Y(), v1.Z(), v1.E());
cout << “Angle of theta (in rad):” << v1.Theta() << endl;
hTheta->Fill(v1.Theta());
}
hTheta->Draw();

but yesterday, after I call some values from the other branches’ of the tree, I started to get Error in TRint::HandleTermInput(): cling::InvalidDerefException caught: Trying to access a pointer that points to an invalid memory address.

O.K. I said I have to start from the beginning to see where the problem is. And wrote this simple macro.

{
TFile* input = new TFile(“genie-nu_tau.root”);
TTree* t = (TTree*)input-> Get(“gst”);

double Ei,pxi,pyi,pzi;

t->SetBranchAddress(“Ei”, &Ei);
t->SetBranchAddress(“pxi”, &pxi);
t->SetBranchAddress(“pyi”, &pyi);
t->SetBranchAddress(“pzi”, &pzi);

Int_t nentries = (Int_t)t->GetEntries();

TH1F *h1=new TH1F(“h1”, “histogramtitle”, 500, 0, 5);

for (Int_t i=0; i<nentries; i++){
t->GetEntry(i);
cout << pxi << endl;
h1->Fill(pxi);
}
h1->Draw();
}

Now I am getting same error. I am sure that the problem is about the GetEntry(i) part or the h1->Fill() part. If I write the loop as:

for (Int_t i=0; i<nentries; i++){
t->GetEntry(i);
cout << pxi << endl;
}

I get pxi values correctly. But when I put the histogram lines to the loop it just gives the first pxi value and than gives Error in TRint::HandleTermInput(): cling::InvalidDerefException caught: Trying to access a pointer that points to an invalid memory address. same error again.

for (Int_t i=0; i<nentries; i++){
t->GetEntry(i);
cout << pxi << endl;
h1->Fill(pxi);
}
h1->Draw();

Do you have any idea why it crashes when I try to fill the histogram like in this simple case?

Thank you so much
Semih

*Br 75 :Ei : Ei[ni]/D *
*Br 76 :pxi : pxi[ni]/D *
*Br 77 :pyi : pyi[ni]/D *
*Br 78 :pzi : pzi[ni]/D *
...
double Ei,pxi,pyi,pzi;
t->SetBranchAddress(“Ei”, &Ei);
t->SetBranchAddress(“pxi”, &pxi);
t->SetBranchAddress(“pyi”, &pyi);
t->SetBranchAddress(“pzi”, &pzi);

This is wrong and fatal. Those branches contains arrays with (likely) more than one element. Upon reading each, it will attempts to write more than one double at each memory location and unavoidably over-write the stack … leading to random behavior including crashes and exception being thrown.
try

double * Ei = new double[max_number_of_element_in_the_array];

Cheers,
Philippe.

All right friends.
I decided to start PyRoot. It is safer for me than the Root itself :slight_smile:
In these 2 weeks period I solved the problem in Python. These arrays were actually multiple arrays and I needed to give a condition to reach them. In this case it is pdgi code. For example:

import ROOT
import math as m

f=ROOT.TFile("genie-nu_tau.root","read")
h1=ROOT.TH1F("h1","h1",100, 0, m.pi)

for event in f.gst:
	for j in range(len(event.Ei)):
		if event.pdgi[j] == 211:	#For some particle
			E_pion  = event.Ei[j]
			px_pion = event.pxi[j]
			py_pion = event.pyi[j]
			pz_pion = event.pzi[j]
			lorentz = ROOT.TLorentzVector()
			lorentz.SetPxPyPzE(px_pion, py_pion, pz_pion, E_pion)
			theta_pion = lorentz.Theta()
			h1.Fill(theta_pion)
			del lorentz
c1 = ROOT.TCanvas()
h1.Draw()
c1.Print('a.png')

But than a file format has changed and now I need to read another tree and this method is not working. I am trying to reach leaves. I saw some approaches and I tried them but they didn’t work. If you have any idea I would appreciate. Again I will use LorentzVector if I can reach them.

and the structure of my tree is the same I think. For example to reach MCTrack I need use fPdgCode also. First let me show you the MCTrack branch first.

This is the first approach:

f = ROOT.TFile("ship.conical.Genie-TGeant4.root")
t = f.Get("cbmsim")

for event in t:         
    # Now I have acess to the leaves/branches of each entry in the tree, e.g.
	for entry in event.MCTrack:
		print entry.fPx

Error: File “Leafread.py”, line 66, in
print entry.fPx
AttributeError: ‘ShipMCTrack’ object has no attribute ‘fPx’

it of course does not recognize fPdgCode leaf, too.

OR

I tried this one which was discussed in forum and worked for others but I get error.

directory = str("ship.conical.Genie-TGeant4.root")
File = ROOT.TChain("cbmsim;14")
File.Add(directory)
Number = File.GetEntries()

for i in range(Number):
	Entry = File.GetEntry(i)
	EntryFromBranch = File.MCTrack.GetEntries()
	for j in range(EntryFromBranch):
		#if File.GetLeaf("MCTrack.fPdgCode").GetValue(j) == 211:
		fPx = File.GetLeaf("MCTrack.fPx").GetValue(j)

Error: File “Leafread.py”, line 57, in
fPx = File.GetLeaf(“MCTrack.fPx”).GetValue(j)
ReferenceError: attempt to access a null-pointer

if I remove the hash of the if statement then I get:

Error: if File.GetLeaf(“MCTrack.fPdgCode”).GetValue(j) == 211:
ReferenceError: attempt to access a null-pointer

I am adding class file here;
TreeAnalysis.C (1.4 KB)
TreeAnalysis.h (53.5 KB)

Thanks a lot,
Semih

could you post somewhere a small ROOT file with that data?

You can download here;
https://drive.google.com/file/d/0B9QpiWvUJBkXeTRYdlNGNWE5WVk/view
400mb

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.