Re: [ROOT] automatic schema evolution

From: Rene Brun (Rene.Brun@cern.ch)
Date: Mon Aug 05 2002 - 23:28:30 MEST


Hi Heather,

We explain this process in the Users Guide.
You can see an example in TAxis::Streamer.

You must have somewhere the old McPositionHit::Streamer.
If you lost it, you can regenerate it by running rootcint
on your old class and specifying
#pragma link C++ class McPositionHit;

Now to generate the new Streamer able to read both the old
class version (before Schema evolution was introduced)
and have the automatic schema evolution for your new versions, 
run rootcint with
#pragma link C++ class McPositionHit-;
and implement the following Streamer function:

void McPositionHit::Streamer(TBuffer &R__b)
{
   // Stream an object of class McPositionHit.

   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      //we use the automatic algorithm for 9eg) class version > 2
      if (R__v > 2) {
         TMcPositionHit::Class()->ReadBuffer(R__b, this, R__v, R__s,
R__c);
         return;
      }
      //====process old versions before automatic schema evolution
      //put here the old read part of the old Streamer
      //====end of old versions

   } else {
      McPositionHit::Class()->WriteBuffer(R__b,this);
   }
}


Rene Brun

On Mon, 5 Aug 2002, Heather Kelly wrote:

> Hi,
> 
> I am using ROOT 3.02.07 on Windows 2000.
> 
> I have a set of ROOT classes, where one class has been updated - where one 
> data member was removed and another one added - and the version incremented.
> My LinkDef file looks like:
> >#ifdef __CINT__
> >
> >#pragma link off all globals;
> >#pragma link off all classes;
> >#pragma link off all functions;
> >
> >#pragma link C++ class VolumeIdentifier+;
> >#pragma link C++ class McParticle+;
> >#pragma link C++ class McPositionHit+;
> >#pragma link C++ class McIntegratingHit+;
> >#pragma link C++ class McEvent+;
> >
> >#endif
> So I am using the "new" Streamer system, and used it all along - starting 
> with the original version of these classes.
> 
> I have an older ROOT file, written with the first version of the classes, 
> and I want to be able to read that file using the new version of the shared 
> library - which contains the updated version of one class.  However, when I 
> do so, using TTree::GetEvent, I receive the following error and warning 
> messages:
> Error in <TBuffer::CheckByteCount>: object of class McPositionHit read too 
> few bytes
> Warning in <TBuffer::CheckByteCount>: McPositionHit::Streamer() not in sync 
> with data on file, fix Streamer()
> 
> I was hoping that upon reading, when it was found that the file contained 
> version 1 of McPositionHit, and the library contained version 3, that the 
> description of the class in the input file would be used to retrieve the 
> data.  Am I doing something wrong?  Or am I just confused?  Must I 
> regenerate the original class library using MakeProject on the old file in 
> order to read this file without problems?
> 
> Thanks,
> Heather
> 



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:03 MET