Appending an object of vector<double> to an existing TBranch

,

Hi there,

I’m having a bit of an issue with a rather large executable. I run a set of calculations that, while not costly to compute, take up a fair bit of memory with the current IO scheme I have.

Basically, I create a bunch of vectors of doubles (say 10 for this example) and append them together into one large vector. I then create a TTree with a TBranch to hold said vector and write everything out at once to a root file (each branch in my TTree has one vector object containing many values in the vector).

What I’d like to do (considering the previous example) is the following: As I run my calculations and create my 10 vectors, I’d like to continuously update ONE TBranch with the latest vector I’ve created. If possible, I’d like to avoid reading in previous data already saved to this TBranch to avoid unnecessary IO. I use unnecessary lightly here because I know what I’m doing is already bad practice, but I’m working with a huge legacy code and I’m in too deep already.

If anyone has any suggestions please let me know! Thanks in advance.

ROOT Version: 6.16.00
Platform: Debian 10
Compiler: g++


Hi Samuel,

I understand you have in an event loop 1 TTree instance per entry

I then create a TTree with a TBranch to hold said vector and write everything out at once to a root file

and you know already this is bad practice

I know what I’m doing is already bad practice

and you want now to have one TTree with one entry per entry in your event loop

I’d like to continuously update ONE TBranch with the latest vector I’ve created. If possible

Please correct me if I am wrong!

If the above is correct, what prevents you to do exactly what you are doing now but not writing the TTree at every event in the file? That is the way TTree has to be used.

Cheers,
D

Not quite. I’ll attempt to layout what I’m doing in some pseudo code here, perhaps that would be more helpful. In the simplest terms, my code works something like this:

// My TTree writing is performed by this method
void WriteTree(vector<double> toWrite){
     TFile* file  = TFile::Open("filename", "RECREATE");
     TTree tree("MyTree", "Hey look at me I'm a tree");
     tree.Branch("myData", &toWrite);
     tree.Fill();
     file->Write();     
     file->Close();
     return;
}

int main(int argc, char* argv[]){
     vector<double> TheBigMainVector;
     for (int i=0; i < 10; i++){
          // dummy method, I get my data from this
          vector<double> data = RunMyCalculations(); 
          for (int j=0; j < data.size(); j++){
               TheBigMainVector.push_back(data[j]);
          }
     }

     WriteTree(TheBigMainVector);
     return 0;
}

What I’d like to do is more akin to this:

void WriteTree(vector<double> toWrite){
     TFile* file;
     if (!gSystem->AccessPathName("filename")){ // if the file exists
          file = TFile::Open("filename", "UPDATE");
     }
     else{
          file  = TFile::Open("filename", "RECREATE");
     }
     TTree tree("MyTree", "Hey look at me I'm a tree");
     // Here is where I want to "append" my new vector to the branch
     tree.Branch("myData", &toWrite); 
     tree.Fill();
     file->Write();     
     file->Close();
     return;
}
int main(int argc, char* argv[]){
     for (int i=0; i < 10; i++){
          // dummy method, I get my data from this
          vector<double> data = RunMyCalculations(); 
          WriteTree(data);
     }
     return 0;
}

Hi,

I see. I do not think we support appending data to a collection which is already in a column f a TTree. You can always write another entry in the TTree and rely on the compression which will be very efficient since many of the entries in this incrementally grown TTree are the same.

Best,
D