Vector of vectors in TTree vs. RNTuple

When I try to set a branch of a vector of vector of floats in a TTree, with the following script, I get an error:

void test() {
    // gInterpreter->GenerateDictionary("vector<vector<float> >","vector");

    TFile * f1 = TFile::Open("ttreetest.root", "RECREATE");

    TTree * t1 = new TTree("tree", "tree");
    std::vector<float> var2;
    std::vector<std::vector<float> > var3;

    t1->Branch("var2", &var2);
    t1->Branch("var3", &var3);

    for (int i=0; i<100; i++) {
        for (int j=0; j<10; j++) {
            var2.push_back(gRandom->Rndm());
            var3.push_back(std::vector<float>());

            for (int k=0; k<10; k++) {
                var3.back().push_back(gRandom->Rndm());
            }
        }
        t1->Fill();
        var2.clear();
        var3.clear();
    }
    t1->Write();
    f1->Close();
}
Error in <TTree::Branch>: The class requested (vector<vector<float> >) for the branch "var3" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (vector<vector<float> >) to avoid to write corrupted data.

I see from previous posts that the dictionary is needed in this case. However, if I try with double instead of float, the code works fine. However, the same is not true for RNTuple:

void rntuple_test() {
    auto model = ROOT::RNTupleModel::Create();
    auto pvar2 = model->MakeField<std::vector<float>>("var2");
    auto pvar3 = model->MakeField<std::vector<std::vector<float> > >("var3");
    auto writer = ROOT::RNTupleWriter::Recreate(std::move(model), "myNTuple", "rntupletest.root");

    // gInterpreter->GenerateDictionary("vector<vector<float> >","vector");
    for (int i = 0; i < 10; ++i) {
        for (int j=0; j<10; j++) {
            pvar2->push_back(gRandom->Rndm());
            pvar3->push_back(std::vector<float>());
            
            for (int k=0; k<10; k++) {
                pvar3->back().push_back(gRandom->Rndm());
            }
        }
        writer->Fill();
        pvar2->clear();
        pvar3->clear();
    }

}

In this case, I don’t need the dictionary for either double or float. Is this expected behavior? Should I expect that floats will be supported without the dictionary in TTrees at some point?


Please read tips for efficient and successful posting and posting code

ROOT Version: 6.36.04
Platform: Almalinux 9
Compiler: Not Provided


Maybe @pcanal can take a look

Check out root/math/mathcore/inc/LinkDef2.h at 78d7bcc0dee75313b70948811568a6576c0dc14a · root-project/root · GitHub

the dictionary for vector<vector<double>> is already defined by ROOT thus you do not need extra work.

there is not the equivalent definition for floats, hence you need to do it manually.

I created [math] add vector of vector of floats dict as with double by ferdymercury · Pull Request #20464 · root-project/root · GitHub

This is all for TTree.
For RNtuple, I think dictionaries are not required, but I am no expert.

1 Like