Fill TTree only once for a value

Dear All,

I’m trying to fill a TTree in multiple circumstances: I have some data from a particle, e.g., electron, with pdg number, name string, among others, that won’t change during my simulation. And have other data e.g. energy that changes during the simulation. I have a limited knowledge of TTree, and the way I’m filling it is in a loop where I store the energy for each step (e.g. in a numerical integration). The thing is that I’m trying to store the constant data in the TTree as well (name, pdg number, others), but they are also filled in the loop, and I end up with a lot of unnecessary (if my loop has 2000 steps, I end up with a branch containing the pdg number 2000 times). I’m sure there are better ways of doing this, but i don’t seem to be able to find a reasonable solution. I have tried as well to use TBranch directly, but didn’t succeed.
Below is a minimally reproducible example. Any inputs are highly appreciated, and thanks in advance.

#include <string>
#include <iostream>

#include <TFile.h>
#include <TTree.h>
#include <TBranch.h>

void fillTTree(){

    TFile file("rootData.root", "recreate");

    int pdg = +11;
    std::string name = "e-";

    double energy = 20.0; // [MeV]

    TTree pTree("electron1", "Particle tree");
    pTree.Branch("pdg", &pdg);
    pTree.Branch("energy", &energy);

    for(int i=0; i<200; i++){
        energy += 0.25;
        pTree.Fill();
    }
    pTree.Write();
    file.Close();
}

_ROOT Version: 6.26/04
_Platform: GNU/Linux Debian 12
_Compiler: CLING


I guess @pcanal can help you.

Dear Leonardo,

Thanks for the post.
If I understand correctly, the issue you highlight is the storage waste resulting from filling the columnar dataset from within a nested for loop: please correct me if I am wrong!
If that’s the concern, I would not worry too much. The columns of a TTree are compressed. If the same number is used for multiple entries, the compression will just be very efficient in squeezing the resulting buffers persistified on storage media.
An option I can see for this particular case, always if I get the context right, is to store the energy of the steps in a collection, say a std::vector<float>, within the event and then store once this container in the event.

I hope this helps and don’t hesitate to come back with questions if needed.

Cheers,
Danilo

1 Like

Dear Danilo,

Thanks a lot for the feedback. And yes, you understood correctly my issue.

I have now stored the values in a vector inside the loop, and finally fill my TTree only once, so it works smoothly.

Thanks for the valuable help.

Leonardo.

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