RE: How to Detect class version of read object?

From: Philippe Canal <pcanal_at_fnal.gov>
Date: Mon, 18 Dec 2006 15:22:50 -0600


Hi Christian,

The code you outline seems to be correct.

However note that:

  1. Having a custom streamer disable split of that class in new TTree
  2. When reading split object in existring file, the streamer is not executed.

If you can make the assumption that files are only written by one original process (aka all the objects in the file have the same version number), then you can use:

 i = (TStreamerInfo*)_file0->GetStreamerInfoList()->FindObject("Data")  i->GetClassVersion();

Otherwise, you can also ask the TTree object:  be = dynamic_cast<TBranchElement*>(mytree->GetBranch("mydata"));  if (be) {

    be->GetInfo()->GetClassVersion();
 }

Cheers,
Philippe.

-----Original Message-----
From: owner-roottalk_at_pcroot.cern.ch [mailto:owner-roottalk_at_pcroot.cern.ch] On Behalf Of Christian Holm Christensen
Sent: Monday, December 18, 2006 2:32 PM
To: ROOT Talk
Subject: [ROOT] How to Detect class version of read object?

Hi all,

I have a data class which unfortunately contains a bug. At the same time, I have a lot of data that's written with that bug. Fortunately it's only one version of the class code that contains that bug, and I have a way to partially recover the data. However, to be able to do that reliably, I need to know the class version of the read object.

That is, class version = 1 contains the bug. So if the code for class version = 2 reads the data written with the code for class version = 1, it should fix up the data.

If I use `obj->Class()->GetClassVersion()' I always get the currently compiled version. So I'm wondering if there's some robust way of getting the version of the code that wrote the data - that is, how do I detect in class code version 2 that the data was written to disk with class code = 1?

I have, what I think is a solution (see the attached 2 scripts). Essentially, I make a custom streamer for class code 2 which is almost exactly like the code generated by rootcint, but in addition it sets a bit in the fBits field to flag if we read an object that was written with the faulty version of the code. However, I'm not sure how robust this method is. The data class will evolve in time, and I really would like to take advantage of ROOT's automatic schema evolution.

To run the example, do

> root -l TestData.C

        Root> WriteIt();

> root -l TestData.C

        Root> ReadIt();

Any ideas are most welcome. Thanks.

Oh, and I'm using 5.13/07 on Debian GNU/Linux unstable, i386, with GCC 4.1.2.

Yours,

-- 
 ___  |  Christian Holm Christensen 
  |_| |  -------------------------------------------------------------
    | |  Address: Sankt Hansgade 23, 1. th.  Phone:  (+45) 35 35 96 91
     _|           DK-2200 Copenhagen N       Cell:   (+45) 24 61 85 91
    _|            Denmark                    Office: (+45) 353  25 404
 ____|   Email:   cholm_at_nbi.dk               Web:    www.nbi.dk/~cholm
 | |
Received on Mon Dec 18 2006 - 22:23:26 MET

This archive was generated by hypermail 2.2.0 : Mon Jan 01 2007 - 16:32:02 MET