Re: Tree Questions

From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri Jan 15 1999 - 17:31:18 MET


Christoph Borgmeier wrote:
> Hello all,
> 
> I think, there could be certain things done to achieve a consistent
> behaviour or slit and non-split Trees and TClonesArrays and polymorphic
> tree entries.
> 
> As I understand it, split TClonesArrays are used to store huge amounts of
> flat rectangular data, similar to the FORTRAN solutions. Graphical objects
> can be stored in a polymorphic way (non-TClonesArray) and are not split.
> This seems to be an object-oriented database. I wonder, if it is possible
> to combine these two approaches smoothly. For reconstructed objects like
> different type of particle patterns and vertices, the polymorphic storage
> seems very attractive.
> 

Hi Christoph,
Thanks for all the contributions to this thread about TTrees.
I was thinking to make a summary this week-end, but your mail
triggered an early reply.
Yes, you are right. We concluded in the same way at the start
of the Root project. One must support two apparent conflicting
requirements:
  - Storage of polymorphic objects (like an OODBMS)
  - Storage of object attributes (like an RDBMS)
A data base will typically be a combination of these 2 modes.
A reconstruction program will typically use more the first form.
A final analysis program will use almost exclusively
the last form (like ntuples).

> I found one problem on each side up to now:
> 
> * The polymorphic version stores objects, which are referenced by others,
> and recreates them when the others are read from the tree. A hashing
> mechanism makes sure, that they are only loaded once per branch. The
> problem is, that they are not deleted, when the next event is loaded. This
> should be simple, since a list of all specially created objects must
> exist. Up to now, I make my own hash table, looking up the TDataMembers.
> That really takes some time. This small extension to ROOT would help a
> lot.

I do not understand this point. Root will automatically delete
any previous object attached to a pointer. You do not need
to delete the objects of the previous event before reading
the second event.

> 
> * The idea of the TClonesArray-Entries is to store mainly scalars, and to
> reference entries of other Arrays by their indices. This is similar to the
> FORTRAN world. The disadvantage is, that it is not self-describing and
> different arrays can be easily confused, e.g. what would be
> 
>   Int_t fcluster;
> 
> if there are several TClonesArrays of reconstructed and Monte-Carlo
> Calorimeter information. Another restriction is, that all instanciations
> of certain classes have to be member of exactly one TClonesArray. (The
> latter might be unavoidable.)

The objects stored in a TClonesArray can be derived from other
objects. However, objects in a TClonesArray must be "Clones",
have the same length. You should not create dynamic objects
withing objects in a TClonesArray. But these objects can be
complex objects.

A TClonesArray IS self-describing. As a proof, you can generate
automatically the analysis code via TTree::MakeClass.
There is also no problems with classes having the same attribute
name in different TClonesArray. A TClonesArray goes to one
super-branch. Each attribute of the referenced class in turn
goes to a separate branch.
During the analysis, an attribute of a class in a TClonesArray
can be referenced by
 - its attribute name if it is unique.
 - branchName.Attributename if it is not unique.


> 
> My proposal would be to create a class around these integers to provide
> the referencation and to guide the compiler and the user. This could be
> done inline for compiled and CINT-interpreted code. Something like this
> (very rough):
> 
> template<class T>
> class TClonesPointer
> {
> public:
>   ...
>   inline T& operator*() const { return *fArray->At( fIdx ); }
>   inline T* operator->() const { return fArray->At( fIdx ); }
>   ...
> private:
>   static TClonesArray* fArray;
>   Uint_t fIdx;
> };
> 
> Note that these objects can have the same memory layout as unsigned int
> (if they are not derived from anything and don't have virtual functions).
> For each template instanciation, one can indicate which array is refered
> to. Maybe like this:
> 
>   TCLonesArray myEllipses("TEllipse");
>   ClonesPointer<TEllipse>::fArray = &myEllipses; // maybe done by some
>                                                  // clever automatism
>   class GoesIntoTheClonesArray
>   {
>     ...
>     ClonesPointer<TEllipse> elli;
>   } x;
> 
>   x.elli = ... ;
> 
>   x.elli->SetX1(.2);
> 
> What do you think?
>

That is what I was calling a TRefList in a previous posting.
Nick West has also addressed this problem in his recent posting.
I agree that this functionality should be provided.
We still have to mature the user interface.

Rene Brun



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:28 MET