Hi all. I’m new to root, and as part of my introduction to it, I’ve been trying to write a user-defined class (my class is named ‘Measurement’) to a TTree. My class is very simple and only contains a vector called ‘measurements’, a double called ‘average’, and an int called ‘counter’. I’ve written a for loop that on each iteration, sets each element of the vector (the size of the vector is randomized each on iteration) to a random value based on a gaussian distribution centered at 511.0. On each iteration of the for loop, I write the class to a tree. However, when I run this program, root crashes and I am left with the following error message:
“Fatal in TBranchElement::InitializeOffsets: Could not find the real data member ‘measurements’ when constructing the branch ‘data1’ [Likely an internal error, please report to the developers].”
The version of root I’m running is 5.34/.34 and my operating system is Ubuntu 14.04. If anyone has any idea on how to fix this, please let me know. Thank you very much.
Here is my code:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
// Root Header Files
#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TFrame.h"
#include "TRandom.h"
#include "TSystem.h"
#include "TBrowser.h"
#include "TBenchmark.h"
#include "TObject.h"
#include "TH1.h"
#ifdef __MAKECINT__
#pragma link C++ class vector<double>+;
#endif
class Measurement : public TObject {
private:
vector<Double_t> measurements;
Double_t average;
Int_t counter;
public:
Measurement() {average = 0.0; counter = 0.0;}
void Measurement::Fill_Vec(Double_t arra[], Int_t length) {
for (Int_t h = 0; h < length; h++) {
measurements.push_back(arra[h]);}
}
void Measurement::Set_Average() {
Double_t sum = 0.0;
for (Int_t y = 0; y < measurements.size(); y++) {
sum += measurements[y];
}
average = sum/(measurements.size());
}
void Measurement::Set_Counter() { counter = measurements.size(); }
void Measurement::Clear_Vec() { measurements.clear(); }
void Measurement::Display_Size() { cout << measurements.size() << endl; }
void Measurement::Display_Content() {
for (Int_t w = 0; w < measurements.size(); w++) {
std::cout << measurements[w] << std::endl;}
}
void Set_Average(Double_t x) {average = x;}
void Set_counter(Double_t y) {counter = y;}
ClassDef(Measurement,1);
};
ClassImp(Measurement);
void tree_with_class_write() {
Measurement *data1 = new Measurement();
srand( time(NULL) );
TCanvas *c = new TCanvas("c","Example Histogram",200,10,700,500);
c->SetFillColor(42);
c->GetFrame()->SetFillColor(21);
c->GetFrame()->SetBorderSize(6);
c->GetFrame()->SetBorderMode(-1);
TH1F* h1 = new TH1F("h1","Gaussian Distribution (mean = 511; deviation = 15)",100,450,575);
h1->SetFillColor(75);
TFile *f = new TFile("class_tree.root","recreate");
TTree *ct = new TTree("class_tree","An example tree using a basic c++ class");
ct->Branch("data1",&data1);
for (Int_t b = 0; b < 25000; b++) {
Int_t n = gRandom->Integer(10);
Double_t ran[n];
for (Int_t j = 0; j < n; j++) {
ran[j] = gRandom->Gaus(511.0,15.0);
h1->Fill(ran[j]);
}
data1->Clear_Vec();
data1->Fill_Vec(ran,n)
data1->Set_Average();
data1->Set_Counter();
ct->Fill();
}
h1->Draw();
f->Write();
delete f;
delete c;
new TBrowser();
ct->StartViewer();
}
void tree_with_class_read() {
}
void tree_with_class() {
gBenchmark->Start("tree_with_class");
tree_with_class_write();
tree_with_class_read();
gBenchmark->Show("tree_with_class");
}