Appending to a TTree

I’m having trouble appending to a TTree, and I can’t figure out what i’m doing wrong. From Adding entries to a TTree it should be straightforward, but i’m finding that branches are being written with seemingly random numbers. For example, filling a branch with an int=5 instead stores 559016324 or something.

I’ve boiled it down to a somewhat less (but still somewhat) complicated example, to try to reproduce the problem with as little code as possible, while not affecting the structure so much as I don’t know where the problem may lie. In this version it seems some of the branches are actually getting properly written - fore example a TGraph seems to be fine here, but basic integers aren’t. (Although for some reason ‘TTree::Scan’ shows the TGraph column 3 times, with only one filled. In the TBrowser things look normal, and I can plot the traces.)

I’ve tried printing out the pointer addresses and making sure everything ties up. One oddity I find is that, when creating a branch, I use mytree->Branch("branchname",&myinteger); then mytree->GetBranch("branchname")->GetAddress() returns the address of myinteger.
On the other hand when i append to the tree, I have to give it the address of a pointer to my integer:

mytree->SetBranchAddress("branchname",&pointertomyinteger);, at which point calling

mytree->GetBranch("branchname")->GetAddress() returns the address of a pointer to myinteger.

So the same code to get the branch address will either return the address of my object, or the address of a pointer to my object, depending on the manner in which the tree was opened. Is that right? It seems odd that the same call will return different things; surely once the tree is open and ready for writing, it should behave the same regardless of preceding details?

I’ve attached the simplified macro.C file. Can anyone help me make sense of why the branches aren’t being filled correctly?

Using ROOT v5.34.
mainmacro.C (3.21 KB)

Try: eventtree->SetBranchAddress("runid",&runid); eventtree->SetBranchAddress("eventid",&eventid); eventtree->SetBranchAddress("eventtrigger",&eventtrigger); eventtree->SetBranchAddress("eventpmtids",&eventpmtidspointer); eventtree->SetBranchAddress("vetotrace",&vetotrace);

[quote=“Pepe Le Pew”]Try: eventtree->SetBranchAddress("runid",&runid); eventtree->SetBranchAddress("eventid",&eventid); eventtree->SetBranchAddress("eventtrigger",&eventtrigger); eventtree->SetBranchAddress("eventpmtids",&eventpmtidspointer); eventtree->SetBranchAddress("vetotrace",&vetotrace);[/quote]
Hi Pepe
That seems to be working! Doesn’t the root documentation say it needs the address of a pointer? Why is that the case only for the vector and tgraph, but not the others?
I had tried this before, but with a universal swap - in that case ROOT complained that SetBranchAddress should be given the address of a pointer, and doesn’t set the address. The call to fill then produces a segfault.

“simple variables” are different from “objects”

Well, I do understand that, but I don’t see any hints of where that distinction is made in the documentation. On root.cern.ch/doc/master/classTT … d5e7898a1d all SetBranchAddress methods that give any description of required arguments simply instruct you to “See the comments in TBranchElement::SetAddress() for the meaning of the addr parameter and the object ownership policy”.
On that page I don’t see anything about “for basic datatypes…”, it just tells you “for top level tree branches … … If addr is not zero, but the pointer addr points at is zero…” from which i take away ‘addr is a pointer to a pointer’.

It also still seems like when creating the branches, I do so with a pointer to my object, but when appending, I use a the address of a pointer to my object. For objects, at least.

[quote]
It also still seems like when creating the branches, I do so with a pointer to my object, but when appending, I use a the address of a pointer to my object. For objects, at least.[/quote]Yes, the TTree::Branch call was (somewhat) recently updated to also allow passing the address of an object (in addition to the address of a pointer). The same upgrade has not yet been done for SetBranchAddress.

Cheers,
Philippe.