Re: your mail

From: Rene Brun (Rene.Brun@cern.ch)
Date: Mon Mar 13 2000 - 21:55:24 MET


Hi Rutger,
Two comments on your object model:
 1- It is illegal to have a TClonesArray of objects where each object
    has a variable length structure. In your case each Track object
    has a variable length list of hits. Simply replace TClonesArray
    by a TObjArray.
 2- I assume that your array of RawHits is already defined as an array
    (TObjArray in your RawEvent object ?).
    If it is a TObjArray (or TClonesArray), I STRONGLY recommend
    having your cladd Track defined as:
    class Track {
    Int_t nhits;
    Int_t *indexArray;
    where indexArray is an array of length nhits containing an index
    to the TObjArray entry in RawEvent.
    This is recommended for many reasons:
      - independency of the memory layout
      - no lengthy conversion of pointers in writing and reading
      - better for storage. The index being typically a small integer
        whereas a pointer will require 4 (if not 8) bytes in the storage.
      - you bypass one level of indirection
      - minimize problems of ownership (with destructors)

If you implement my recommendations above, your new Tree will contain
  - one branch with the raw event
  - one branch with the reconstructed tracks

The scheme will also work if you keep your original class Track class
as it is, but replacing TClonesArray by TObjArray in RecoEvent AND
not use the split mode.

Also note that (as suggested by Pasha) you can also have the elegant
solution of having two Trees in the same file: One Tree for RawEvent,
One Tree for RecoEvent with my suggestion of using an indexArray
instead of pointers.

Rene Brun



On Mon, 13 Mar 2000, Rutger van der Eijk wrote:

> Hi,
> 
> 
> I have a problem storing reconstructed data together with raw data in one
> file. I think it boils down to the following:
> 
> 
> In a raw data file ("RawFile.root") I have a TTree ("rawTree") with a
> single branch of RawEvent s. Where the RawEvent has, among other items, a
> TClonesArray of RawHit s. I.e.;
> 
> ---------
> class RawHit;
> 
> 
> class RawEvent {
> private:
> 
>  TClonesArray* fRawHitCont; // clones array of RawHit (owner)
> ...
> public:
> 
> ...
> }
> ---------
> 
> In a reconstruction program I read the raw events from the raw data file.
> And reconstruct some objects (tracks, etc..). Some of the reconstructed
> objects have pointers to raw objects (e.g. a Track has pointers to hits).
> Therefore in the reconstructed event class has, among pointers to the
> reconstructed objects, a pointer to the RawEvent. I.e.,
> 
> ---------
> class RecoEvent {
> private:
>   RawEvent* fRawEvent; // pntr to raw event
>   TClonesArray* fTrackCont; // clonesarray of Track (owner)
> ...
> public:
> 
> ...
> }
> 
> 
> class Track {
> private:
>   TList* fHitCont; // container with RawHit (not owner)
> 
> ...
> public:
> 
> ...
> }
> ----------
> 
> 
> Now I want to store this whole structure in a new file ("RecoFile.root").
> So I fill a branch in a TTree ("recoTree") in the file "RecoFile.root"
> with RecoEvent s. This in order to have as well the raw as the
> reconstructed information in a single file, such that further analysis can
> be done on this file without the raw file.
> 
> The problem:
> If I just use the standard created streamers in the simple case above the
> RawHit s are written twice. Hence when I read back the file the RawHit
> objects pointed to by the Track s are not the same as the RawHit s
> pointed to by RawEvent. 
> 
> So, I think for some reason the mechanism that ensures objects are written
> only once (for objects pointed to multiple times) does not work. I suspect
> it has something to do with the fact that the RawEvent I READ is in a
> different tree (RawTree) than the reconstructed event (RecoTree). But I do
> want to SAVE the RawEvent in the reconstructed tree via the RecoEvent.
> What am I doing wrong, and how can I achieve what I want?
> 
> thanks,
> 
> Rutger
> 
> 
> 



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:21 MET