Well, after a hard day’s work on the question I think I no longer understand anything at all!!! I have attached what started out as an attempt to give the simplest possible example of my problem. In the end, I am not able to reproduce the problem I first reported; instead, I now have another problem which I will try to explain.
Un-tar the .tar.gz, ‘cd’ to the directory TRefArrayExample directory you just created, and type ‘make’ to build the shared library libTRAE.so (if ROOTSYS is not defined, you’ll need to type ‘make ROOT_MAKEFILE_PATH=/some/path…’ with the path to wherever $ROOTSYS/test/Makefile.arch is hidden on your system).
Once the .so has been built, you can create a ROOT file containing a few detectors and a TTree with 10 events (each event contains a TClonesArray of particles, each particle contains a TRefArray with references to the detectors). Launch ROOT and do:
root [0] .L libTRAE.so
root [1] .L TRAEMain.cxx+
root [2] TRAEMain m
root [3] m.WriteTree()
You should see something like:
Info in <TRAEDetector::Streamer>: Called
Info in <TRAEDetector::Streamer>: Called
Info in <TRAEDetector::Streamer>: Called
Info in <TRAEDetector::Streamer>: Called
Info in <TRAEDetector::Streamer>: Called
### EVENT NUMBER 1 ###
Info in <TRAEEvent::Print>: Event with 10 particles :
TRAEParticle::Part_1_Event_1 fNumDet=1
OBJ: TRAEDetector Det_1 TRAEDetector object
TRAEParticle::Part_2_Event_1 fNumDet=2
OBJ: TRAEDetector Det_1 TRAEDetector object
OBJ: TRAEDetector Det_2 TRAEDetector object
TRAEParticle::Part_3_Event_1 fNumDet=5
OBJ: TRAEDetector Det_1 TRAEDetector object
OBJ: TRAEDetector Det_2 TRAEDetector object
OBJ: TRAEDetector Det_3 TRAEDetector object
OBJ: TRAEDetector Det_4 TRAEDetector object
OBJ: TRAEDetector Det_5 TRAEDetector object
TRAEParticle::Part_4_Event_1 fNumDet=2
OBJ: TRAEDetector Det_1 TRAEDetector object
OBJ: TRAEDetector Det_2 TRAEDetector object
where you can see for each particle of each event, the number of associated detectors (fNumDet), and the list of detectors.
Now quit ROOT and start a new session, this time do
root [0] .L libTRAE.so
root [1] TFile f("TRefArrayExampleTree.root")
root [2] .ls
TFile** TRefArrayExampleTree.root
TFile* TRefArrayExampleTree.root
KEY: TRAEDetector Det_1;1 TRAEDetector object
KEY: TRAEDetector Det_2;1 TRAEDetector object
KEY: TRAEDetector Det_3;1 TRAEDetector object
KEY: TRAEDetector Det_4;1 TRAEDetector object
KEY: TRAEDetector Det_5;1 TRAEDetector object
KEY: TProcessID ProcessID0;1 926cfe4e-e18e-31dd-8001-9a3cca1cdd73
KEY: TTree Run;1 TTree with event objects
The referenced detectors are written in the file, along with the TProcessID object. Now read in the detector objects:
root [3] f.Get("Det_1")
Info in <TRAEDetector::Streamer>: Called
(class TObject*)0x917f1d0
root [4] f.Get("Det_2")
Info in <TRAEDetector::Streamer>: Called
(class TObject*)0x90a0208
etc. etc. and then connect the TTree and read an event:
root [5] TRAEEvent* event = 0
root [6] Run->SetBranchAddress("Event",&event)
root [7] Run->GetEntry(0)
Info in <TRAEEvent::Streamer>: Called
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=1
Collection name='TRefArray', class='TRefArray', size=5
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=2
Collection name='TRefArray', class='TRefArray', size=5
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=5
Collection name='TRefArray', class='TRefArray', size=5
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=2
Collection name='TRefArray', class='TRefArray', size=5
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=3
Collection name='TRefArray', class='TRefArray', size=5
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=5
Collection name='TRefArray', class='TRefArray', size=5
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=4
Collection name='TRefArray', class='TRefArray', size=5
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=3
Collection name='TRefArray', class='TRefArray', size=5
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=4
Collection name='TRefArray', class='TRefArray', size=5
Info in <TRAEParticle::Streamer>: Called
Read fNumDet=4
Collection name='TRefArray', class='TRefArray', size=5
(Int_t)(913)
root [8] event->Print()
Info in <TRAEEvent::Print>: Event with 10 particles :
TRAEParticle::Part_1_Event_1 fNumDet=1
TRAEParticle::Part_2_Event_1 fNumDet=2
TRAEParticle::Part_3_Event_1 fNumDet=5
TRAEParticle::Part_4_Event_1 fNumDet=2
TRAEParticle::Part_5_Event_1 fNumDet=3
TRAEParticle::Part_6_Event_1 fNumDet=5
TRAEParticle::Part_7_Event_1 fNumDet=4
TRAEParticle::Part_8_Event_1 fNumDet=3
TRAEParticle::Part_9_Event_1 fNumDet=4
TRAEParticle::Part_10_Event_1 fNumDet=4
As you can see, the number of detectors was correctly stored, but the references to the detectors have been lost. On further investigation, the TRefArray of each particle is not in fact empty, it does contain the correct ‘unique ID’ for each detector it references, the fPID of the TRefArray is the right one (i.e. the one in the TFile), but the object cannot be retrieved from the TProcessID. In TRefArray::At, the call to fPID->GetObjectWithID returns 0x0, event though both fPID and the ID are correct:
inline TObject *TRefArray::At(Int_t at) const
{
// Return the object at position i. Returns 0 if i is out of bounds.
int j = at-fLowerBound;
if (j >= 0 && j < fSize) {
if (!fPID) return 0;
/*** obj = 0x0 after the next line ***/
TObject *obj = fPID->GetObjectWithID(fUIDs[j]);
/*** even though fPID and fUIDs[j] are correct ***/
if (obj==0) obj = GetFromTable(j);
return obj;
}
BoundsOk("At", at);
return 0;
}
I suppose I must now be doing something completely wrong. Can you help me please ?
Thanks a lot.
John
TRefArrayExample.tar.gz (62 KB)