TTree::Draw and automatic schema evolution

I would like to ask how can I use automatic schema evolution when I call TTree::Draw in interactive session.

For a test I tried followings.

  1. Create a file with a class.

[code]// myclass.h
#include "TNamed.h"
class myclass: public TNamed
{
public:
Double32_t a;
myclass();
myclass(const char* name);
ClassDef(myclass,1);
};

#ifdef MAKECINT
#pragma link C++ class myclass+;
#endif[/code]

[code]// myclass.cc

#include "myclass.h"
ClassImp(myclass)
myclass::myclass() {}
myclass::myclass(const char* name){SetName(name);}[/code]

// testclass.cc #include "myclass.cc" #include "TFile.h" #include "TTree.h" #include "TClonesArray.h" int main() { TFile f("test.root","recreate"); TTree *tree = new TTree("tree", "tree"); TClonesArray *array = new TClonesArray("myclass"); tree->Branch("a", "TClonesArray", &array, 32000, 99); array->ExpandCreate(1); ((myclass*) (array->At(0)))->a = 4; tree->Fill(); f.Write(); }

$ rootcint -f dict.cc -c myclass.h+
$ g++ -Wall root-config --libs --cflags -o testclass testclass.cc dict.cc
$ ./testclass

  1. Change the class structure

[code]// new myclass.h
#include "TNamed.h"
class myclass: public TNamed
{
public:
Double_t a; // <== changed type
myclass();
myclass(const char* name);
ClassDef(myclass,2); // <== increamented
};

#ifdef MAKECINT
#pragma link C++ class myclass+;
#endif[/code]

  1. Read the file

$ root root [0] .L myclass.cc+ root [1] TFile f("test.root") root [2] tree->Draw("a")

Then what I see in TCanvas is a histgram with an entry at 0 instead of 4.
When I enable debugging messages, it says as following. So ROOT notices the structure has been changed.

[code]====>Rebuilding TStreamerInfo for class: myclass, version: 1
Creating StreamerInfo for class: myclass, version: 2

StreamerInfo for class: myclass, version=2, checksum=0xd3a58282
TNamed BASE offset= 0 type=67 The basis for a named object (name, title)
Double_t a offset= 28 type= 8
i= 0, TNamed type= 67, offset= 0, len=1, method=0
i= 1, a type= 8, offset= 28, len=1, method=0
Warning in TStreamerInfo::BuildOld: element: myclass::Double32_t a has new type: Double_t/8

StreamerInfo for class: myclass, version=1, checksum=0x70d1912d
TNamed BASE offset= 0 type=67 The basis for a named object (name, title)
Double32_t a offset= 28 type= 9
i= 0, TNamed type= 67, offset= 0, len=1, method=0
i= 1, a type=209, offset= 28, len=1, method=0[/code]

I am aware that it works when I don’t call “.L myclass.cc+”, but this is just a sample code to reproduce my problem. What I really do is using the same binary to write and read trees which is linked with my own classes.

with respect

Hi,

The problem is now corrected in the SVN trunk.

You also have 3 work around:

  • compile your script via ACLiC
  • usemyclass * m = ((myclass*) (array->At(0))); m->a = 4;
  • initialize the data member of the class: myclass::myclass() : a(0) { };

Cheers,
Philippe.

Thank you for your reply.

I have tried SVN revision 22245, but it does not seem my problem is fixed.
I have also included your second and third suggestions.
I am testing on SL4 on 32 bit i686 CPU.
If you need more information to reproduce the problem, please let me know.

I tried also making an application to read the file.
Procedure 1 and 2 are common with the previous post.

3’-1. Recreate dictionary.
$ rm dict.cc dict.h
$ rootcint -f dict.cc -c myclass.h+

3’-2. Read the file with an application.

// testclass2.cc #include "myclass.cc" #include "TFile.h" #include "TTree.h" #include "TPostScript.h" int main(int argc, char **argv) { TFile f("test.root"); TTree *tree = (TTree*)f.FindObjectAny("tree"); TPostScript ps("test.ps"); tree->Draw("a.a"); }

g++ -Wall root-config --libs --cflags -o testclass2 testclass2.cc dict.cc
./testclass2
gv test.ps

Ryu

Hi,

With the fix, I can not longer reproduce this problem. Note that the problem is while writing the file (i.e. you need to rewrite it before the problem goes away).
To help in reproducing the problem that you still have, please upload a tar file with all the files (and makefile if any) that you use (and instructions) :slight_smile:

Cheers,
Philippe.

Hi.

Thank you for your help.

I attached a tar.gz file. It includes a makefile so that you can do the same procedure by just typing ‘make’.
treetest.tar.gz (10.2 KB)

Hi,

Thanks for this complete example :slight_smile:. I can now reproduce the problem (which in the TTreeFormula mechanism and should be fixed shortly).

You can work around the problem by introducing a getter member function (GetA() for example) and using it to plot the values (tree->Draw("mybranch.GetA());

Cheers,
Philippe.

Hi,

The problem is now fixed in the SVN trunk.

Thanks for your report.

Philippe

Hi.

Now SVN trunk is fine.

Thank you for your help.

Ryu