This is a follow-up post of Proper way to store an event into a Tree
Thanks to @bellenot I managed to store an “event” (containing only a single ID integer field) into a tree.
I am facing issues when storing a more complex structure. I want my events to store a container of “tracks” which in turn store a container of “steps”. I have managed to store my tracks into the event via an std::vector
(I think the proper way to do this is via TClonesArray
but don’t know how to do this, advice is welcome).
However I cannot store the steps into my tracks, they do not get saved into the ttree.
A minimal example to reproduce this is available at GitHub - lobis/root_event_tree_cmake at a2018d8b9b2d09dd6355259ff85331321f0e275f
Code:
// DataModel.h
class Step {
public:
Int_t fStepID;
Step() {}
~Step() {}
};
class Track {
public:
Int_t fTrackID;
std::vector<Step> fSteps;
Track() {}
~Track() {}
};
class Event : public TObject {
public:
Int_t fEventID;
Event() {}
~Event() {}
std::vector<Track> fTracks;
ClassDefInline(Event, 1);
};
// main.cpp
#include <TFile.h>
#include <TInterpreter.h>
#include <TTree.h>
#include <iostream>
#include "DataModel.h"
using namespace std;
int main() {
TString filename = "tree.root";
TString treeName = "tree";
gInterpreter->Declare("#include \"DataModel.h\"");
auto tree = new TTree(treeName, "My Tree");
auto event = new Event();
tree->Branch("fEvents", &event);
for (int i = 0; i < 100; i++) {
event->fEventID = i;
for (int j = 0; j < 10; j++) {
Track track;
track.fTrackID = j;
for (int k = 0; k < 20; k++) {
Step step;
step.fStepID = k;
track.fSteps.push_back(step);
}
event->fTracks.push_back(track);
}
tree->Fill();
}
auto file = new TFile(filename, "RECREATE");
tree->Write();
file->Close();
delete file;
cout << "READING TREE..." << endl;
file = new TFile(filename);
file->ls();
file->GetObject(treeName, tree);
tree->Print();
tree->Show(0);
}
And a sample of the output:
/tmp/tmp.5hQmftc1lu/cmake-build-debug/root_event_tree_cmake
Warning in <TClassTable::Add>: class Event already in TClassTable
READING TREE...
TFile** tree.root
TFile* tree.root
KEY: TTree tree;1 My Tree
******************************************************************************
*Tree :tree : My Tree *
*Entries : 100 : Total = 4463365 bytes File Size = 46925 *
* : : Tree compression factor = 99.26 *
******************************************************************************
*Branch :fEvents *
*Entries : 100 : BranchElement (see below) *
*............................................................................*
*Br 0 :fUniqueID : UInt_t *
*Entries : 100 : Total Size= 981 bytes File Size = 99 *
*Baskets : 1 : Basket Size= 32000 bytes Compression= 4.81 *
*............................................................................*
*Br 1 :fBits : UInt_t *
*Entries : 100 : Total Size= 1369 bytes File Size = 286 *
*Baskets : 1 : Basket Size= 32000 bytes Compression= 3.08 *
*............................................................................*
*Br 2 :fEventID : Int_t *
*Entries : 100 : Total Size= 976 bytes File Size = 247 *
*Baskets : 1 : Basket Size= 32000 bytes Compression= 1.92 *
*............................................................................*
*Br 3 :fTracks : Int_t fTracks_ *
*Entries : 100 : Total Size= 4588 bytes File Size = 440 *
*Baskets : 1 : Basket Size= 32000 bytes Compression= 2.00 *
*............................................................................*
*Br 4 :fTracks.fTrackID : Int_t fTrackID[fTracks_] *
*Entries : 100 : Total Size= 203650 bytes File Size = 2824 *
*Baskets : 7 : Basket Size= 32000 bytes Compression= 71.90 *
*............................................................................*
*Br 5 :fTracks.fSteps : vector<Step> fSteps[fTracks_] *
*Entries : 100 : Total Size= 4253508 bytes File Size = 41009 *
*Baskets : 87 : Basket Size= 32000 bytes Compression= 103.67 *
*............................................................................*
======> EVENT:0
fEvents = (Event*)0x55e0d6e56fc0
fUniqueID = 0
fBits = 50331648
fEventID = 0
fTracks = (vector<Track>*)0x55e0d6e56ff0
fTracks.fTrackID = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
fTracks.fSteps = (vector<Step>*)0x55e0d6e8a778, (vector<Step>*)0x55e0d6e8a798, (vector<Step>*)0x55e0d6e8a7b8, (vector<Step>*)0x55e0d6e8a7d8, (vector<Step>*)0x55e0d6e8a7f8, (vector<Step>*)0x55e0d6e8a818, (vector<Step>*)0x55e0d6e8a838, (vector<Step>*)0x55e0d6e8a858, (vector<Step>*)0x55e0d6e8a878, (vector<Step>*)0x55e0d6e8a898
Process finished with exit code 0
Also it want to point out that when opening the tree.root
file, I get the following warnings:
root [0]
Attaching file tree.root as _file0...
Warning in <TClass::Init>: no dictionary for class Event is available
Warning in <TClass::Init>: no dictionary for class Track is available
(TFile *) 0x5557791d6290
I find it interesting that there is no warning for a dictionary of Step
.