Re: [ROOT] Changing class definition in split level=2

From: Rene Brun (Rene.Brun@cern.ch)
Date: Tue Aug 14 2001 - 16:18:52 MEST


Hi Daniel,

If you want to rename one or more leaves from a TBranchClones
to match the names in your new class MyClass, eg change from "sect"
to "sector", you can do the following:
   TFile f("oldfile.root");
   TTree *T = (TTree*)f.Get("T");
   TClass *cl = gROOT->GetClass("MyClass");
   if (!cl->GetListOfRealData())  cl->BuildRealData();
   TRealData *rd = (TRealData*)cl->GetListOfRealData()->FindObject("sector");
   TLeaf *leaf = T->GetLeaf("sect");
   leaf->SetOffset(rd->GetThisOffset());

Then, you set your branch address as usual for the TClonesArray and do
T->GetEntry(..). The "sector" data member of your new class MyClass
will be correctly filled with the value in the leaf "sect"

Rene Brun

Magestro Daniel wrote:
> 
> Rene,
> 
> Hi - after further thought it occurs to me that, in split level=2, we face a
> major problem (unless I am completely misunderstanding something).  If the
> streaming is done by TBranchClones, then old datamember names can never be
> 'assigned' to the new name. (We are interested in changing many of our
> datamember names.)  This step is necessary to make the class's getters work
> with the old files (our datamembers are protected) and, as I understand, is
> usually taken care in the class streamer:
> 
>    if (R__v < 2) {
>       R__b >> sector;
>       sect = sector;
>    } else R__b >> sect;
> 
> If the class streamer is never called, this assignment (sect = sector) is
> never performed and the class getters cannot be used at all.  How is this
> taken care of in the old or new ROOT?
> 
> My only ideas are to write additional getter's for the old datamember names
> (ugly solution!) OR to invent a local class which somehow makes all the
> assignments between old and new datamember names.  Or, we lose the ability
> to read old files with a new class definition.
> 
> The most likely solution is that we (1) lose backward compatibility and
> finish migrating to Root 3.01, (2) invoke the new BypassStreamer() function
> of TClonesArray, and (3) make our datamember name changes and continue to
> use custom streamers.  Otherwise I do not see how we can ever do more than
> simply reading trees once the class def changes for split level=2...
> 
> Thanks for the extra attention you've given to this,
> Dan
> 
>  -------------------------------------------
> |  Daniel Magestro        +44-6159-71-2147  |
> |  magestro@gsi.de        GSI/Kernphysik I  |
> |  www.gsi.de/~magestro   Planckstr. 1      |
> |    < last updated >     64291 Darmstadt   |
> |    < Aug 6, 2001  >     Germany           |
>  -------------------------------------------
> 
> 
> | From: Rene Brun [mailto:Rene.Brun@cern.ch]
> | Sent: Tuesday, August 14, 2001 9:48 AM
> | To: Magestro Daniel
> | Subject: Re: [ROOT] Changing class definition in split level=2
> |
> | Hi Daniel,
> |
> | What you see seems to be TTree::Draw problems and not I/O problems.
> | Could you send me (not to the list) a tar file with:
> |   - a copy of an old small file
> |   - a copy of a new small file
> |
> | Rene Brun
> |
> | Magestro Daniel wrote:
> | >
> | > Rene,
> | >
> | > Hi - as a test regarding the use of split level=2 and class
> | def changes, I
> | > have compiled our code with ROOT v3.01 including a simple
> | change of one
> | > datamember name (OLD=sector, NEW=sect).  When I read in an
> | old DST file that
> | > was created with the original class def (we used ROOT
> | v2.25), I see the
> | > original datamember name 'sector' in the TBrowser. However,
> | when I do a
> | > TTree->Draw(), I get the following error message:
> | >
> | >   root [2] T->Draw("HMdcCal1.fData.sector")
> | >     Error in <TTreeFormula::DefinedVariable>: sector is not
> | a datamember of
> | >     HMdcCal1
> | >
> | > In other words, the old datamember name is not known any
> | longer. Also,
> | > although the new datamember name doesn't show up in the
> | TBrowser, I *can* do
> | > a TTree->Draw(), which returns only -1's (sect's initialized value):
> | >
> | >   root [3] T->Draw("HMdcCal1.fData.sect")
> | >     <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
> | >
> | > This seems quite strange to me. The TBrowser shows the old
> | name which cannot
> | > be drawn, but the new name is not shown but CAN be drawn.
> | >
> | > If I do a T->MakeCode() and look at the generated macro,
> | the original
> | > datamember name is listed as a leaf:
> | >
> | >   ....
> | >
> | T->SetBranchAddress("HMdcCal1.fData.sector",HMdcCal1_fData_sector);
> | >   ....
> | >
> | > Clearly there is some difficulty in reading old files if
> | the class def has
> | > changed, even for tree drawing.  Do you have any
> | suggestions?  Is this due
> | > to the change in the schema for TBranchClones?
> | >
> | > Thanks again for your support, you've been really helpful...
> | > Dan
> | >
> 
> (see roottalk for further messages)



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:57 MET