TTree with 'C struct'

Dear you,

My ROOT is: ROOT 5.27/02 (trunk@33229…

I construct a TTree branch with a C struct as following (please pay attention to those ‘float’ data):

struct PPAC
{
	unsigned short C2Px1,C2Px2,C2Py1,C2Py2;
	float C2Px,C2Py;
	unsigned short T2P1t,T2P1x1,T2P1x2,T2P1y1,T2P1y2;
	float T2P1x,T2P1y;
	unsigned short T2P2t,T2P2x1,T2P2x2,T2P2y1,T2P2y2;
	float T2P2x,T2P2y;
};

for this data structure, those ‘float’ values always be very stange in the Tree(Please check the attached ps file).

However, if I change the ‘C struct’ to the following structure:

struct PPAC
{
	unsigned short C2Px1,C2Px2,C2Py1,C2Py2;
	unsigned short T2P1t,T2P1x1,T2P1x2,T2P1y1,T2P1y2;
	unsigned short T2P2t,T2P2x1,T2P2x2,T2P2y1,T2P2y2;

	float C2Px,C2Py;
	float T2P1x,T2P1y;
	float T2P2x,T2P2y;
};

the ‘Tree’ is correct.

I use the TTree function

TBranch* Branch(const char* name, void* address, const char* leaflist, Int_t bufsize /* = 32000 */)

to build the ‘Branch’. The ‘leaflist’ have been checked carefully (especially the ‘/F’ and ‘/s’, “C2Px1/s:… C2Px/F:…T2P1t/s:…” or “C2Px1:/s…T2P2y2/s:C2Px/F:…”) to match the C struct respectively.

Because the size of my binary data file is big, so I can not update it.
But, if you can not reproduce this problem, please reply the post, I will prepare a simple program.

Thank you!
Handong
T2P1x.ps (10.3 KB)

It may be a “structure padding” problem, I believe.
Try:

g++ -Wpadded -o PPAC PPAC.cxx ./PPAC
Then try (note the difference between the interpreted and the compiled code below):

root [0] .x PPAC.cxx root [1] .x PPAC.cxx++
PPAC.cxx (729 Bytes)

Dear Pepe Le Pew,

Thank you very much!
This problem confused me a long time. I won’t make this mistake next time.

Best wishes
Handong

Hi,

Because of the difference in padding between the compiler, the interpreter and the guess made by TTree, we recommend to either sort the data member in the struct by decreasing size (double first, then float, then int, the n short) or to create a separate branch for each data member or (the best solution) to create a dictionary for the struct and use the object based interface which will get the right offset in all cases).

Cheers,
Philippe.

Dear Philippe,
Thank you very much.
As you post this message, I recover that I had read this information somewhere else (in the ROOT manual or Reference), however I do not understand it and not take it in mind. From now on, I won’t make this mistake.

Best wishes,
Handong

See “==> Case” A, B and C here: http://root.cern.ch/root/html/TTree.html
I think the best idea would be to “create a dictionary for the struct and use the object based interface” (i.e. “==> Case” B and/or C), as mentioned by Philippe. Moreover, a dictionary for the struct will also prevent problems when mixing compiled and interpreted code (which uses this struct). So, even if you don’t want to use “==> Case” B nor C, you should still create/load the dictionary for the struct (try the attached “pad.cxx” file).
See also Philippe’s reply, which is an example of how to “create a separate branch for each data member” (the “Bundle” could be your “PPAC”, while “fOne” and “fTwo” could be your “C2Px1”, “C2Px2”, and so on), here: [url]How to pre process TSelector. Discussion
pad.cxx (1.6 KB)

Dear Pepe Le Pew,

Thank you.

I understand this problem very clearly now. I have tried the ‘dictionary’ method, it is very good.

Cheers,
Handong