Reading vector branches in GUI

Hi, I’m trying to write a display (GUI) that can read vectors from a tree and display them.
However, it seems that the branches are read properly but the vectors then do not exist.

In fact, running the following script I get:

[code]#include
#include
#include
#include
#include

#include “TApplication.h”
#include “TSystem.h”
#include <TMath.h>
#include <TROOT.h>
#include <TGClient.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TFile.h>
#include <TTree.h>
#include <TLine.h>
#include <TRandom.h>

#include <TGButton.h>
#include <TGFrame.h>
#include <TRootEmbeddedCanvas.h>
#include <RQ_OBJECT.h>

#define PI 3.14159265

class MyMainFrame {
RQ_OBJECT(“MyMainFrame”)
private:
TGMainFrame *fMain;
TRootEmbeddedCanvas *fEcanvas;
TCanvas *fCanvas;
TFile *input;
TTree *tree;
int nentries;
int entry;

public:
MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h);
virtual ~MyMainFrame();
void DoDraw();
void DoExit();
void CreateCanvas(void);
void ReadTree();
};

MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) {
// Create a main frame
fMain = new TGMainFrame(p,w,h);

// Create canvas widget
fEcanvas = new TRootEmbeddedCanvas(“Ecanvas”,fMain,800,800);
fMain->AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandX| kLHintsExpandY,
10,10,10,1));

// Create a horizontal frame widget with buttons
TGHorizontalFrame *hframe = new TGHorizontalFrame(fMain,800,40);

TGTextButton *draw = new TGTextButton(hframe,"&Random");
draw->Connect(“Clicked()”,“MyMainFrame”,this,“DoDraw()”);
hframe->AddFrame(draw, new TGLayoutHints(kLHintsCenterX,5,5,3,4));

TGTextButton *exit = new TGTextButton(hframe,"&Exit");
exit->Connect(“Clicked()”,“MyMainFrame”,this,“DoExit()”);
hframe->AddFrame(exit, new TGLayoutHints(kLHintsCenterX,5,5,3,4));

fMain->AddFrame(hframe, new TGLayoutHints(kLHintsCenterX,2,2,2,2));

// Set a name to the main frame
fMain->SetWindowName(“Cluster Display”);

// Map all subwindows of main frame
fMain->MapSubwindows();

// Initialize the layout algorithm
fMain->Resize(fMain->GetDefaultSize());

// Map main frame
fMain->MapWindow();

ReadTree();
CreateCanvas();

}

void MyMainFrame::ReadTree()
{
input = TFile::Open(“outputMap.root”);

if(!input) {
  std::cerr << "Couldn't read file!\n";
  exit(1);
}

tree = (TTree*) input->Get("tree");
if(!tree) {
      std::cerr << "Couldn't find 'tree'!\n";
      exit(1);
    }
nentries = (Int_t)tree->GetEntries();
std::cout << " Tree Entries: " << nentries << std::endl;

}

void MyMainFrame::CreateCanvas(void)
{
fCanvas = fEcanvas->GetCanvas();
fCanvas->Divide(1,2);
}

void MyMainFrame::DoExit()
{
input->Close();
gApplication->Terminate(0);
}

void MyMainFrame::DoDraw()
{
std::vector * Positions = 0;
std::vector * Charges = 0;

tree->SetBranchAddress("SVDClusters.m_pos", &Positions);
tree->SetBranchAddress("SVDClusters.m_charge", &Charges);

// get random entry
srand (time(NULL));
entry = rand() % nentries + 1;
tree->GetEntry(entry);

if (Positions->empty()) {
  std::cout << " empty vector " << std::endl;
}
else {
  std::cout << " size is  "<< Positions->size() << std::endl;
  
  tree->ResetBranchAddresses(); // detach from local variables
 delete Positions;
 delete Charges;

}

MyMainFrame::~MyMainFrame() {
// Clean up used widgets: frames, buttons, layouthints
fMain->Cleanup();
delete fMain;
}
void NewDisplay() {
// Popup the GUI…
new MyMainFrame(gClient->GetRoot(),800,800);
}
[/code]

Hi,

Could you provide your data file (output.root)?

Cheers, Bertrand.

In the end of “void MyMainFrame::DoDraw()”, you need to add:
tree->ResetBranchAddresses(); // detach from local variables
delete Positions;
delete Charges;

Thanks for your answers.

In the meantime I switched to ROOT6, made sure the file compiles fine and added the lines about deleting the pointers (code updated in my first post).

Now the error that I get while I try to use DoDraw is the following ( which I think still means the same thing, vectors are not filled with the tree content and so don’t exist)

I also attach to root file I’m using.

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007f48c8a4468e in waitpid () from /lib64/libc.so.6
#1  0x00007f48c89d6609 in do_system () from /lib64/libc.so.6
#2  0x00007f48c99a8d07 in TUnixSystem::StackTrace() () from /cvmfs/belle.cern.ch/sl6/externals/v01-01-01/Linux_x86_64/opt/root/lib/libCore.so
#3  0x00007f48c99aac0c in TUnixSystem::DispatchSignals(ESignals) () from /cvmfs/belle.cern.ch/sl6/externals/v01-01-01/Linux_x86_64/opt/root/lib/libCore.so
#4  <signal handler called>
#5  0x00007f48c9f214bc in ?? ()
#6  0x0000000002c882f0 in ?? ()
#7  0x00007f48c9f2126c in ?? ()
#8  0x0000000000000000 in ?? ()
===========================================================


The lines below might hint at the cause of the crash.
If they do not help you then please submit a bug report at
http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#5  0x00007f48c9f214bc in ?? ()
#6  0x0000000002c882f0 in ?? ()
#7  0x00007f48c9f2126c in ?? ()
#8  0x0000000000000000 in ?? ()
===========================================================

outputMap.root (29.7 KB)

It looks like the root file is being downloaded already 5 times, any ideas if the problem is in the root file or in the code ?

Hi,

We are investigating…

Cheers, Bertrand.

Hi,

if you want to read these two branches holding an stl vector in the file you posted, the procedure can be:

   TFile f("outputMap.root");
   TTree* t = nullptr;
   f.GetObject("tree",t);

   TTreeFormula formula("formula","SVDClusters.m_charge",t);
   for (int entry=0;entry< t->GetEntries();++entry){
      t->LoadTree(entry);
      const auto size = formula.GetNdata();
      cout << "  o Size is " << size << endl;
      for(int i = 0; i < size; ++i) {
         auto charge = formula.EvalInstance(i);
         cout << "    * " << charge << endl;
      }
   }

Cheers,
Danilo

Thanks for your answer. I got some work with higher priority but will report if this method works for me. Cheers