Hello,
I’m getting a weird issue when trying to read out values from a TTree branch stored in a ROOT file. I originally persisted the following class to file (12x to the same TTree):
// `Results` has no data members that are written to file
class MyResults : public Results {
public:
std::vector<int> activity;
std::vector<int> occupancy;
int timesteps;
double foo;
};
I write this object to file as such:
TFile tfile("results.root", "UPDATE");
// If ROOT file existed, get the TTree object
TTree *tree = static_cast<TTree *>(tfile.Get("binding_cells"));
// If ROOT file didn't exist before, our TTree* is a nullptr
if (tree == nullptr) {
// Create new TTree and pass the name and description to it
tree = new TTree("binding_cells", "T-Cell_Activity_Study");
// Write the results to file under the specified branch name
// (I get the object in as a function argument)
tree->Branch("binding_cells", obj);
} else { // If ROOT file did exist, we should append to existing TTree
// Make a local copy of the object pointer
auto *obj_ptr = obj;
// Append to branch
tree->SetBranchAddress("binding_cells", &obj_ptr);
}
tree->Fill();
tfile.Write();
In PyROOT I do:
// Load the dictionary of MyResults and Results
ROOT.gSystem.Load("results_dict.so");
f = TFile("results.root");
results = gROOT.FindObject("binding_cells")
results.Print()
******************************************************************************
*Tree :binding_cells: T-Cell_Activity_Study *
*Entries : 12 : Total = 38757 bytes File Size = 7747 *
* : : Tree compression factor = 5.28 *
******************************************************************************
*Branch :binding_cells *
*Entries : 12 : BranchElement (see below) *
*............................................................................*
*Br 0 :bdm::Results : *
*Entries : 12 : Total Size= 1748 bytes File Size = 1272 *
*Baskets : 12 : Basket Size= 32000 bytes Compression= 1.00 *
*............................................................................*
*Br 1 :activity : vector<int> *
*Entries : 12 : Total Size= 16233 bytes File Size = 1608 *
*Baskets : 12 : Basket Size= 32000 bytes Compression= 9.75 *
*............................................................................*
*Br 2 :occupancy : vector<int> *
*Entries : 12 : Total Size= 16249 bytes File Size = 1584 *
*Baskets : 12 : Basket Size= 32000 bytes Compression= 9.90 *
*............................................................................*
*Br 3 :timesteps : Int_t *
*Entries : 12 : Total Size= 1633 bytes File Size = 1068 *
*Baskets : 12 : Basket Size= 32000 bytes Compression= 1.00 *
*............................................................................*
*Br 4 :foo : Double_t *
*Entries : 12 : Total Size= 1585 bytes File Size = 1044 *
*Baskets : 12 : Basket Size= 32000 bytes Compression= 1.00 *
*............................................................................*
When I do
for event in results:
# same with event.timesteps
print(event.foo)
<ROOT.bdm::MyResults object at 0x7f4b43ec8bd0>
<ROOT.bdm::MyResults object at 0x7f4b43ec8bd0>
<ROOT.bdm::MyResults object at 0x7f4b43ec8bd0>
...(12x in total)...
However doing print(event.activity)
or print(event.occupancy)
, I do get the values shown. It seems like only for integral values types that I get the address to the object back.
I also tried the same steps with C++ notebooks, using TTreeReaderValue<vector<int>>
and TTreeReaderValue<int>
, and there it seems to read out all the branches correctly.
Am I doing something wrong, or is this supposed to work?
Cheers,
Ahmad
ROOT Version: 6.18
Platform: CentOS 7
Compiler: GCC 7.3.0