Reading exactly 1 leaf from TChain

Hi,
I wonder how to properly read exactly one leaf from TChain. This is more like a feature request.

Supposed my tree is created with

tree.Branch("mybranch",&somevoidpointer,"n/I:array[n]/F")

I make the array with variable length right in the middle on purpose. When writing this file the tree knows exactly how many bytes it needs to write.

However, there will be a problem in reading this tree through normal TChain interface. Ideally I’d want to set the address of leaf “n” to something and read it first before reading the “array” leaf. So I know exactly how many bytes I need for “array” field and can make sure I don’t write beyond the memory I own. This can be done in TTree FindBranch FindLeaf and SetAddress and TLeaf GetEntry to read only the leaf I want and see if I need to realloc memory for “array”.

However, for TChain, FindBranch FindLeaf and SetAddress will only set the address for local branch. The only interface(as far as I know) to read TChain branches is SetBranchAddress which will work with global branch as expect. However, there is no way I’d know how many bytes I need for this branch and this particular entry before it gets written and potentially buffer overflow.

So, my question is is there something similar like SetLeafAddress(“branchname”,“leafname”,somepointer,TLeaf**) that works with TChain global leaf properly? I couldn’t find it in the documentation though.

Thanks,
Piti

Hi,

When using the leaflist branch creation technique, creating several leaf in a branch means that you will have to read those leaves always together. To change this, use different branches:tree.Branch("mybranch_n",&(somepointer->n),"n/I"); tree.Branch("mybranch_array",&(somepointer->array),"array[n]/F");

Cheers,
Philippe.

Thanks Philippe.

But, I’m trying to create a fast root to numpy array converter that will take arbitrary and convert them properly. And ROOT doesn’t seem to disallow this type of thing so I want to support it. I’m digging deeper in TChain TBranch TLeaf code. And I think I solved the problem.

Is the following correct?: It seems like there is actually no need to set address on branch or leaf. I can always get the pointer to the value I need by TLeaf::GetValuePointer() and the number of bytes i need to copy by doing TLeaf::GetLenType()*TLeaf::GetLen()? I’m guessing this is probably some mmap chunk of memory which is likely to change every time I call GetEntry(even without loading new tree)? And ROOT will ensure somehow that mmap chunk of memory will be large enough to contain all the element in the array(that is the array is not cut off at the end of mmap chunk). Thus, there is no need for me to need to know in advance how many bytes a branch need (since I do not supply any of my own buffer).

Then, for global TLeaf I can just mimic TChain by keeping a dictionary of branchname+leafname to TLeaf** and update the TLeaf** everytime I load a new file. I think this is a non-issue.

Piti

[quote]Is the following correct?: It seems like there is actually no need to set address on branch or leaf. I can always get the pointer to the value I need by TLeaf::GetValuePointer() and the number of bytes i need to copy by doing TLeaf::GetLenType()*TLeaf::GetLen()?[/quote]Yes.

[quote]I’m guessing this is probably some mmap chunk of memory which is likely to change every time I call GetEntry(even without loading new tree)?[/quote]Well, usually the address are allocated only once per TTree (i.e. the address will change when using a TChain and moving across file boundaries).

[quote]Thus, there is no need for me to need to know in advance how many bytes a branch need (since I do not supply any of my own buffer).[/quote]Yes, this is the safest easiest (and is how TTreeFormula works).

[quote]Then, for global TLeaf I can just mimic TChain by keeping a dictionary of branchname+leafname to TLeaf** and update the TLeaf** everytime I load a new file. I think this is a non-issue.[/quote]Yes (and again this is how TTreeFormula works).

Cheers,
Philippe.