Data Model Evolution - Arrays

Hello,

A given class which is used as a container and whose objects are stored in ROOT files needs to be updated.
To be more precise, the data consumption has to be minimized by going from Int_t to Char_t or similar for the data members.
As far as I understood, for simple conversions of variables it is enough to increase the class version number and the rest will be done automatically.
For more complicated transformations to stay backward compatible and be able to read old files I was pointed at the manual data model evolution:
http://root.cern.ch/svn/root/trunk/io/doc/DataModelEvolution.txt

My question is now if this is also applicable for multi-dimensional arrays.

In the actual case I tried to translate an old Int_t 2-dim array into the new 2d Char_t array:

#pragma read \ sourceClass = "AliTRDCalDCSFEE" \ targetClass = "AliTRDCalDCSFEE" \ version = "[-4]" \ source = "Int_t fGainTableAdcdac" \ target = "fGainTableAdcdac" \ targetType = "Char_t" \ code = "{ Char_t* gtc=&fGainTableAdcdac; Int_t* gti=&onfile.fGainTableAdcdac; for(Int_t i=0; i<(8*18); i++) *(gtc+i) = *(gti+i); }"

It compiles but when accessing an old ROOT file I get memory corruptions:

*** glibc detected *** aliroot: malloc(): memory corruption: 0x000000001e06a670 *** ======= Backtrace: ========= /lib64/libc.so.6[0x3daac72f39] /lib64/libc.so.6(__libc_malloc+0x6e)[0x3daac74bee] /usr/lib64/libstdc++.so.6(_Znwm+0x1d)[0x3ee32bd17d] /local/kramer/alice/root/lib/libCore.so(_ZNK5TCint16CallFunc_FactoryEv+0x17)[0x2b44711c72fd] /local/kramer/alice/root/lib/libCore.so(_ZNK6TClass23CalculateStreamerOffsetEv+0x50)[0x2b447119ba10] /local/kramer/alice/root/lib/libCore.so(_ZNK6TClass8StreamerEPvR7TBufferPKS_+0x26d)[0x2b447119c25d] /local/kramer/alice/root/lib/libRIO.so(_ZN11TBufferFile13ReadObjectAnyEPK6TClass+0x115)[0x2b44724111c5]

I also tried to do the translation in various other ways, e.g. not using pointer arithmetics but always get this kind of an error.
Am I just doing it wrong or is this model simly not forseen to be used with multi-dimensional arrays?

Thanks a lot and best regards
Frederick

Hi,

Indeed there seems to be some problems with associating a rule with an array. Note that your rule should read:#pragma read \ sourceClass= "AliTRDCalDCSFEE" \ targetClass = "AliTRDCalDCSFEE" \ version = "[-4]" \ source = "Int_t *fGainTableAdcdac" \ target = "fGainTableAdcdac" \ code = "{ fGainTableAdcdac = new Char_t[8*18]; Char_t* gtc=fGainTableAdcdac; Int_t* gti=onfile.fGainTableAdcdac; for(Int_t i=0; i<(8*18); i++) *(gtc+i) = *(gti+i); }"i.e. the targetType does not need to be specified and the source need to have the correct type. (Also you need to remove any space between the sourceClass and the equal to avoid a bug fixed only by revision r34630

More importantly note that the translation from Int_t *fArray; to Char_t *fArray; is one of the default supported translation.

Cheers,
Philippe.

humm … actually what is the actual definition your data member before and after?

Hi,

Support for rules for data member that are static size array or variable size array has been fixed/enabled in revision 34641 of the trunk.

Cheers,
Philippe.

Hi,

thanks for your reply.
The definition of the data member was before:

and is now:

With:

static const Int_t fgkROB = 8; static const Int_t fgkMCM = 18;

You wrote that this kind of a translation is a default one, does this mean that I don’t have to write a streamer rule myself? Or is this what has been enabled since trunk rev. 34641?

Cheers
Frederick

[quote]You wrote that this kind of a translation is a default one, does this mean that I don’t have to write a streamer rule myself?[/quote]Indeed it is the default., there is no need for a streamer rule in this case.

[quote] Or is this what has been enabled since trunk rev. 34641?[/quote]I enabled the ability to write stremaer rules that override this default behavior (in case for example where you need to not only change from Int_t to Char_t but also change the values.

Cheers,
Philippe.