Not being able to write RVec<PtEtaPhiMVector> object into root file with RDF snapshot

Hi @yburkard ,

Although it’s a bit hidden, the real error of your example is the line

logic_error: Trying to insert a null branch address.

In my case, I get a much more verbose error.

Error in <TTree::Branch>: The class requested (ROOT::VecOps::RVec<ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> > >) for the branch "Electrons" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (ROOT::VecOps::RVec<ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> > >) to avoid to write corrupted data.
RDataFrame::Run: event loop was interrupted
Error in <TTree::Branch>: The class requested (ROOT::VecOps::RVec<ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> > >) for the branch "Electrons" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (ROOT::VecOps::RVec<ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> > >) to avoid to write corrupted data.
RDataFrame::Run: event loop was interrupted
Traceback (most recent call last):
  File "/home/vpadulan/Projects/rootcode/forum-posts/53129/test.py", line 5, in <module>
    .Snapshot("tree", "file.root", ("Electrons"))
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I’m using Python 3.11 and ROOT 6.26.10, what are your Python and ROOT versions?

Now, for an answer to your problem, this is another case of missing dictionaries for your custom collection class, as it has also happened in the past, for example here and here.

So you need to generate dictionaries for the class ROOT::VecOps::RVec<PtEtaPhiMVector>. The easies way for your original example could be the following

#include <ROOT/RDataFrame.hxx>
#include <iostream>
#include <ROOT/RVec.hxx>
#include <Math/Vector4D.h>
#include <TInterpreter.h>

int main()
{
   gInterpreter->GenerateDictionary("ROOT::RVec<ROOT::Math::PtEtaPhiMVector>", "Math/Vector4D.h;ROOT/RVec.hxx");
   ROOT::RDataFrame df{5};
   df.Define("Electrons",
             [] {
                return ROOT::RVec<ROOT::Math::PtEtaPhiMVector>{{1, 2, 3, 4}, {1, 2, 3, 4}};
             })
      .Snapshot("tree", "file.root", {"Electrons"});
}

Or the equivalent in Python:

import ROOT

if __name__ == "__main__":
    ROOT.gInterpreter.GenerateDictionary(
        "ROOT::RVec<ROOT::Math::PtEtaPhiMVector>", "Math/Vector4D.h;ROOT/RVec.hxx")
    ROOT.RDataFrame(5)\
        .Define("Electrons", "ROOT::RVec<ROOT::Math::PtEtaPhiMVector>{{1, 2, 3, 4}, {1, 2, 3, 4}}")\
        .Snapshot("tree", "file.root", ("Electrons"))

For more complicated custom classes, see the manual.
Cheers,
Vincenzo

1 Like