Optimizing code to read a TBranch of arrays of unkown size, and store it in a std::vector

Hello,

I have a question about how to improve my code.

I have to read a TBranch which every entry is vector of floats (*Br 3 :timing_par : timing_par[3]/F ), and ‘a priori’, I don’t know the size of this vector (this should be parameterized in the code).
I’m doing it like this:

TFile *f  =  TFile::Open("file.root");
TTree* tt =  (TTree*)f->Get("mytree");
std::vector<std::vector<float>> library;
read_lib(tt,library,3);

void read_lib(TTree* tt, std::vector<std::vector<float>> library, int NPAR){
Double_t   *par = nullptr;
for(size_t i=0; i!=tt->GetEntries(); ++i) {
   tt->Draw("timing_par","","goff",1,i);
   par=tt->GetV1();
   for (size_t j=0; j<NPAR; ++j) library[i][j]=par[j];
}

It works fine, but it is very slow. I think it is because I have to store this values in a std::vector<std::vector>, and to do so, I have to go entry by entry converting the doubles into float, and this is very slow.

I cannot do the SetBranchAdress to an usual float array, because I get this error:

error: ISO C++ forbids variable length array ‘test’ [-Werror=vla]
     Float_t test[NPAR];

Any idea is welcome!

J


ROOT Version (e.g. 6.12/04):
Platform, compiler (e.g. CentOS 7.3, gcc6.2):


Hi,

trying to clarify your case here.
You have a dataset a column of which stores vector instances. You would like to “extract” this column as a data structure in memory. Is this correct?

Cheers,
D

Hi dpiparo,
Thanks for you answer. Yes, this is basically what I do with the code above, but I don’t know which is the more efficient-fast way.
The Branch is defined as “timing_par[3]/F”, a vector of floats, but I could change this definition if there is a better way.
The only requirement is that the size of the vector should be parametrised…

Regards,
José

Hi Jose,

I propose to solve this with TDataFrame:

ROOT::Experimental::TDataFrame d("mytree", "file.root");
// auto c = d.Take<std::vector<float>>("v"); // a bit slower, reallocations possible
auto v = d.Take<std::vector<float>, std::deque<std::vector<float>>>("v");

Cheers,
Danilo

For completeness sake (because the DataFrame solution is ‘better’), you can use

  Float_t *test - new Float_t[NPAR];
  ...
  tree->SetBranchAddress(branchname,&(test[0]));

Cheers,
Philippe.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.