Keeping objects in memory

Hi, I would like to do an operation for which I do not find any reference in the documentation.
I have a class called BxEvent and a class called bx_phys_event which inherits from BxEvent. My data are stored in root files using a branch of BxEvent.
The bx_phys_event add to the parent some methods which are needed by the high level analysis.
I would like to keep a list of bx_phys_event loaded from the root file, with something similar to

bx_phys_event *e; std::vector<bx_phys_event *> v; f = new TFile (filename.c_str (), "read"); tree = f->Get ("bxtree"); branch = tree->GetBranch("events"); branch->SetAddress (&e); for (int i = 0; i < 1000; i++) { e = new bx_phys_event ; tree->GetEntry (i); e->other_info_not_in_bx_event = ... v.push_back (e); }
The point is that it does not work: the first poin is that I can not leave the creation of the object to the branch, since I need to create a bx_phys_event instead of BxEvent. On the countrary if I do not set “e=0” GetEntry uses always the same storage for the object, and than the list contains invalid objects.

Is there any solution? (I would like not copy from BxEvent to bx_phys_event istances for efficency)

Hi,

The following should work:

std::vector<bx_phys_event *> v; f = new TFile (filename.c_str (), "read"); TTree *tree; f->GetObject("bxtree"); TBranch *branch = tree->GetBranch("events"); for (int i = 0; i < 1000; i++) { bx_phys_event *phys = new bx_phys_event ; BxEvent *e = phys; // To insure proper alignment branch->SetAddress (&e); // Inform the tree of the new address tree->GetEntry (i); phys->other_info_not_in_bx_event = ... v.push_back (phys); }

Now it might be as efficient (i.e. at least it is the same number
of object creation!) to do:

std::vector<bx_phys_event *> v; f = new TFile (filename.c_str (), "read"); TTree *tree; f->GetObject("bxtree"); BxEvent *e = 0; tree->SetBranchAddress("events",&e); for (int i = 0; i < 1000; i++) { tree->GetEntry (i); bx_phys_event *phys = new bx_phys_event(*e) ; phys->other_info_not_in_bx_event = ... v.push_back (phys); }

Cheers,
Philippe

Philippe thanks for your repply; the first code I put was only an example. In my project I would create a pool of space for 1000 events and then use only that pool. The event sould be added to the top of a list and removed from the bottom to avoid using more than 1000 entries.

This way I can redefine the new operator and the overhead for this operation should be much lower.

The point is that I know that SetBranchAddress is a long operation; is there any faster way?

Ciao Alessandro

[quote]The point is that I know that SetBranchAddress is a long operation; is there any faster way? [/quote]The only 2 options I can think of are to call SetBranchAddress or to copy the data. Somehow TTree has to be told where to copy the data to. Either this location does not change (and you need to copy) or it does change (and SetBranchAddress need to be called).

Note that in ROOT 5.02/00, we greatly improved the performance of SetBranchAddress, when used repetitively.

[quote]this way I can redefine the new operator and the overhead for this operation should be much lower. [/quote]Good. And I think you can still use this technique in conjunction with my second code sample.

I think your issue is now basically to compare the cost of
"SetBranchAddress" and the cost of copying the data between 2 BxEvent objects (since in both case you can avoid memory allocation). I would bet that the copy is faster but you could only know after testing the 2 options.

Cheers,
Philippe