if I may ask on this topic, somehow related question, I managed to store a ROOT::VecOps::RVec<ROOT::VecOps::RVec<>> in my output files, but even with properly generating the specific dictionary in my LinkDef.h I am never able to read it back with root (v06.22) without a seg fault. Using std::vector<std::vector<>> works just fine as expected. Is this an expected behaviour?
Cheers,
Clement
Hi,
how did you write RVecs out and what does tree->Print() show for that output TTree?
I/O of RVecs if a bit flaky currently, that’s why e.g. RDataFrame does not write out RVecs but always std::vectors, performing an on-the-fly conversion if needed. We are going to fix it in a backward-incompatible way in the next ROOT version, so writing RVecs to disk at the moment is discouraged (v6.24 will print a warning).
Oh, I see. I tried as much as possible use RVec everywhere even writing them in the TTree (I build a dictionary of C++ functions that returns RVecs). I should then change to std::vectors following your statement.
Below is a print of the ttree where you see one output RVec that works: jets_kt_pz my vector<vector> that also works jetconstituents_kt but the RVec of RVec of int jetconstituents2_kt does not.
The file looks fine, those are actually all std::vectors (with a custom allocator, but ROOT I/O does not care) – probably thanks to that on-the-fly conversion that Snapshot does.
Thank you for sharing the file, can you please also share a snippet of code that crashes when reading it?
From what you posted above, you are not storing RVecs, you are storing std::vectors (probably thanks to Snapshot performing this on-the-fly conversion I mentioned). I will check the actual file and get back to you.
yes, I understood that, sorry for not being clear enough. I’m wondering if I should avoid using the OTF conversion by directly using std::vectors, or would that have a negligible impact on performance?
In 6.22, the conversion has zero overhead. In 6.24, the conversion will have a little overhead. In 6.26, there will be no conversion and I/O of RVecs will work just fine (even better – you will be able to write std::vectors and read them as RVecs and vice-versa with pure ROOT I/O).
Bottom line: sorry for the trouble, we are making things better, and I will let you know why TTree::Scan crashes
Thanks @eguiraud for looking into it and very good to hear that this is already in the pipeline.
I will be using std::vector of std::vectors in the mean time. Issue understood, so I mark it with solution.
Cheers,
Clement
Alright, I will soon have a test in for I/O of RVec<RVec<T>> and RVec<RVec<RVec<T>>> (just to be sure), where T is a fundamental type. Your LinkDef reminds me that it’s better to also test the case in which T is a user-defined class.
Anyway, I will ping you here when ROOT’s master branch has support and test coverage for these cases, thank you for bringing this up.