Re: [ROOT] Trees, ClonesArrays and an obsolete call error

From: Hamlet (_hamlet@libero.it)
Date: Sun Aug 03 2003 - 22:08:04 MEST


(18:35, mercoledì 23 luglio 2003, Philippe Canal)
> The problem has been fixed.  Please try the version in the CVS
> repository and let me know if you any other problems.

First of all, thank for your readiness!
I must say the problem is half fixed, since it persists in derived 
classes. Try the following code (I would send as attachment... are 
attached files allowed in this ML?).
The scheme is like the one in the previous mail, but the object which 
will fill the tree (STreeEvent) holds a derived class (FittedList) of 
an object (PhotonsList) with a pointer to a TClonesArray.
Compiling with rootcint (3.05/07 CVS of few days ago) and gcc (3.2) and 
issuing following commands from root.exe:

[0] .x STreeEvent.so
[1] STreeEvent* pEvent = new STreeEvent; pEvent->Init();
[2] TTree tree; tree.Branch("Event", "STreeEvent", &pEvent);

the resulting message is:

Error in <TBranchElement::GetDataMemberOffset>: obsolete call with 
(FittedList,Fit)

(note that before your patch this one would have had a similar one about 
its parent class).


// begin of code - STreeEvent.h
#ifndef __STREEEVENT_H
#define __STREEEVENT_H


#include <TClonesArray.h>

class PhotonsList: public TObject {
    public:
  TClonesArray* pPhotons; //photons data

  PhotonsList() { pPhotons = NULL; }
  ~PhotonsList() {
    if (!pPhotons) return;
    pPhotons->Delete();
    delete pPhotons;
    }

  void Init() { pPhotons = new TClonesArray(TObject::Class(), 8); }

  ClassDef(PhotonsList,1) //list of photons for an event
}; // PhotonsList


class FittedList: public PhotonsList {
    public:
  FittedList(): PhotonsList() {}
  
  ClassDef(FittedList,1) //fitted event
}; // FittedList


class STreeEvent: public TObject {
    public:
  FittedList Fit;                 //fitted data

  void Init() { Fit.Init(); }

  ClassDef(STreeEvent,1) //event encapsulated in a tree
}; // STreeEvent

#endif // __STREEEVENT_H
// end of code - STreeEvent.h

Surrounding files:

// begin of code - STreeEvent.cpp
#include "STreeEvent.h"

ClassImp(PhotonsList)
ClassImp(FittedList)
ClassImp(STreeEvent)
// end of code - STreeEvent.cpp


// begin of code - STreeEventLinkDef.h
#ifdef __CINT__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ class PhotonsList;
#pragma link C++ class FittedList;
#pragma link C++ class STreeEvent;

#endif
// end of code - STreeEventLinkDef.h


-- 
Hamlet



> -----Original Message-----
> From: owner-roottalk@pcroot.cern.ch
> [mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Hamlet
> Sent: Tuesday, July 22, 2003 6:02 PM
> To: roottalk
> Subject: [ROOT] Trees, ClonesArrays and an obsolete call error
>
>
> Hello!
>
> While messing with TTrees, I've run into the following error:
>
> Error in <TBranchElement::GetDataMemberOffset>: obsolete call with
> (PhotonsList,Clusters)
>
>
> The object I'm going to write in TTree is something which recall this
> scheme:
>
> // start of code
> class PhotonsList: public TObject {
>     public:
>   TClonesArray* pPhotons; //photons data
>
>   PhotonsList() { pPhotons = NULL; }
>   ~PhotonsList() {
>     if (!pPhotons) return;
>     pPhotons->Delete();
>     delete pPhotons;
>     }
>
>   void Init() { pPhotons = new TClonesArray(TObject::Class(), 8); }
>
>   ClassDef(PhotonsList,1) //list of photons for an event
> }; // PhotonsList
>
>
> class STreeEvent: public TObject {
>     public:
>   PhotonsList Clusters;           //original photons data
>
>   void Init() { Clusters.Init(); }
>
>   ClassDef(STreeEvent,1) //event encapsulated in a tree
> }; // STreeEvent
> // end of code
>
> Linking header file is:
>
> // start of code
> #ifdef __CINT__
>
> #pragma link off all globals;
> #pragma link off all classes;
> #pragma link off all functions;
>
> #pragma link C++ class PhotonsList;
> #pragma link C++ class STreeEvent;
>
> #endif
> // end of code
>
> while the object file (namely, STreeEvent.cpp) is the couple of calls
> to macro to implement classes (ClassImp).
>
> That is to say, I've a class fated to be main tree branch
> (STreeEvent) which directly holds a TObject derived class, which has
> a pointer to a clones-array of photons (a TObject or whatever); this
> pointer is not initted in constructor since some tutorials teach so.
>
> Now with CINT and ROOT 3.05/06 the sequence:
>   // loads object code to CINT:
> [0] .x STreeEvent.so
>   // create and init an object:
> [1] STreeEvent* pEvent = new STreeEvent; pEvent->Init();
>   // create a tree and a branch with that object as address:
> [2] TTree tree; tree.Branch("Event", "STreeEvent", &pEvent);
>
> that message prints out. It's very reasonable that a call to
> TBranchElement::GetDataMemberOffset(PhotonsList,Clusters) fails,
> since there is no "Clusters" field in PhotonsList and Clusters is a
> field /of type/ PhotonsList (in another object).
> I could bet that with 3.05/05 this did not happen, but I'm not sure.
> I've no idea whether this is a message that can be safely ignored or
> not.
>
> Written enough. Any suggestion?
>
> --
> Hamlet



This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:14 MET