Split-Level with Vector of TLorentzVector


Maybe the problem I see is simply related to the fact that I did not understand correctly the meaning of split-level when defining a tree, but hopefully you experts can help me/explain it to me (I use ROOT Version 5.13/04e):

In my analysis code I am saving particles in an event as a vector of TLorentzVectors. I use:


std::vector MuonRec;
std::vector *fMuonRec;

fMuonRec = &MuonRec;
fTree->Branch(“MuonRec”, “std::vector”, &fMuonRec, 32000, 0); //set split-level for 3D-vector to zero!

TLorentzVector Muon(muon->px(), muon->py(), muon->pz(), muon->energy());


This works perfectly fine, in the root-file I can browse the tree and look at the muon-vectors.

Still then I have a C++/ROOT-programm running over the root-file and analyzing the tree again. I use:


std::vector *fMuonRec;
TBranch *b_fMuonRec;

fChain->SetBranchAddress(“MuonRec”, &fMuonRec, &b_fMuonRec);

So here is the question/problem:
All works fine if I specify split-level=0, but using the default value 99 the code fails and I get some segmentation-violation. Saving a vector of numbers also split level 99 works, so the problem seems to be related to the TLorentzVector.
Is it only possible to save vectors of vectors using split-level=1? Is this somehow because of the different coordinates of the TLorentzVector?

Thanks for any comments!

Philipp Biallass

Before setting the branch address, you must set the pointer to null:

std::vector<TLorentzVector> *fMuonRec=0;

Sorry, I forgot this line in the pasted code.
Actually I do set fMuonRec=0 before setting the BranchAdress in my code analyzing the tree.
Still the program crashes when using default split-level, but works fine with zero split-level.

Is it possible that the problem has some other origin?

Thanks again!


Hi Philipp,

This is odd :slight_smile:. Can you provide a script reproducing the problem (my attempts failed to produce any crashes).


PS. You have std::vector<TLorentzVector> *fMuonRec = 0; TBranch *b_fMuonRec; fChain->SetBranchAddress("MuonRec", &fMuonRec, &b_fMuonRec);You need to make sure that the fMuonRec does not go out of scope before you do the GetEntry (otherwise you will have a crash).


The problem is solved.
If I set fChain->SetMakeClass(0) instead of the SetMakeClass(1) I had before the program works, also when reading back a tree with default split-level.

So somehow the default split-level interferes with the SetMakeClass option. Can this be understood?
Notice that SetMakeClass(1) was included in the code by the MakeClass skeleton analysis. I did not include it myself.

Thanks anyway



[quote]If I set fChain->SetMakeClass(0) instead of the SetMakeClass(1) [/quote]This makes complete sense :slight_smile:

SetMakeClass(1) is explicitly incompatible with reading objects. The point of SetMakeClass is to tell the TTree that the data is going to be read piece-meal using individual int, floats, etc and array of int, floats, etc. (See the .h produce by MakeClass).

It means that the ‘object’ I/O is by passed, intentionally. This render readying the data via object (like your vector) incorrect (at the very least the object virtual table is not correctly set).