Hi
I already sent this message to the roottalk list with no response, actually
this is just an excuse to try the new ROOT forum. Any reply gratefully received!!
John
I have a problem with non-persistent data members in objects stored in a TTree when the objects in
question have a custom streamer. It seems that each call to TTree::GetEntry wipes the current value
of the non-persistent data member, by a call to the default ctor for the class. This behaviour is not
observed when using an automatically generated streamer, even if in fact the custom streamer is nothing
but a copy of the automatically generated one. I have attached some files which demonstrate the problem.
I am using the 3.05/07 binary for RH9 with gcc 3.2.2
The class TestPersist has two data members, a and b. a is persistent, b non-persistent.
The method TestPersist::IsOK() returns kTRUE if a > b, and kFALSE otherwise.
I generate a TTree filled with TestPersist objects using the script TestPersist_Tree.C.
100 ‘events’ are generated with “a” taking the values 0,1,2,…,99.
The AnalPersist analysis class was generated from the TTree with MakeSelector.
This analysis sets a “threshold” value b=50 in the Begin() method, and then fills
a histogram with the value of “a” for each “event” with TestPersist::IsOK() = kTRUE.
When I use an automatic streamer (rootcint -f TestPersist_Dict.cxx -c TestPersist.h)
I get the result I want, i.e. a histogram which is filled from a=51 up to 99.
The “b” histogram shows that the value I set in Begin() i.e. 50 is not affected by
the reading of objects from the TTree, as one expects.
However, with a customised streamer (rootcint -f TestPersist_Dict.cxx -c TestPersist.h-),
which is in fact an exact copy of the one generated in the previous case,
the “a” histogram is filled with all values from 0 to 99, and indeed this is because
the value of “b” is not 50 but 0. I checked that this is due to the default ctor being called
by changing the initialisation in TestPersist::TestPersist() to “b=20”. In this case I find that
the value of “b” is always 20.
In my “real-life” problem I have no choice but to use a customised streamer.
Can you tell me how to get the same behaviour for non-persistent members in this case
as when using an automatic streamer ? (preferably I would like to keep the initialisation
of the non-persistent members in the default ctor!!)
Thankyou very much.
John.
PS. I made the CINT dictionary for the class using
rootcint -f TestPersist_Dict.cxx -c TestPersist.h
Then I compiled the class and the dictionary and built an .so:
g++ -c root-config --cflags
-oTestPersist.o TestPersist.C
g++ -c root-config --cflags
-oTestPersist_Dict.o TestPersist_Dict.cxx
g++ -shared root-config --libs
-olibTestPersist.so TestPersist.o TestPersist_Dict.o
Then at the ROOT command line I did:
.L libTestPersist.so
.L TestPersist_Tree.C+
write_tree()
in order to create and fill the TTree. Then in a new ROOT session I do:
.L libTestPersist.so
TFile f(“test_persist.root”)
t1->Process(“AnalPersist.C+”)
In the case of a customised streamer I uncommented the line
#define CUSTOM_STREAMER
in TestPersist.h, built the dictionary using
rootcint -f TestPersist_Dict.cxx -c TestPersist.h-
and then repeated all the other steps in order.
testpersist.h (1.53 KB)
analpersist.h (4.73 KB)
TestPersist_Tree.C (505 Bytes)