I have a question about the behavior of Aliases in RDataFrames. Naively I would have expected, that an Alias is really just a different name for a column or in our case a branch. However, from the following minimal reproducer that does not seem to be the case:
We store vector<ObjectID>
that look like the following in some of our branches
struct ObjectID {
ObjectID() = default;
ObjectID(int c, int i) : collID(c), index(i) {}
int collID{};
int index{};
};
Consider a Tree that has been filled with vector<ObjectID>
in the following way
import ROOT
ROOT.gInterpreter.GenerateDictionary("ObjectID;std::vector<ObjectID>", "ObjectID.h")
ROOT.gInterpreter.Declare('''
#include "ObjectID.h"
void fillTree(const char *tn, const char *fn) {
ROOT::RDataFrame df(10);
df.Define("ObjectIDs", []() {
constexpr auto N = 3;
std::vector<ObjectID> ids;
ids.reserve(N);
for (int i = 0; i < N; ++i) {
ids.emplace_back(i, i*i);
}
return ids;
}).Snapshot<std::vector<ObjectID>>(tn, fn, {"ObjectIDs"});
}
''')
ROOT.fillTree("example_tree", "example_df.root")
With this the following works
df = ROOT.ROOT.RDataFrame("example_tree", "example_df.root")
df.Define("idx", "ObjectIDs.index")
However, if I first make an alias and then try to do the same:
df = ROOT.ROOT.RDataFrame("example_tree", "example_df.root")
df.Alias("ids", "ObjectIDs").Define("idx", "ids.index")
This breaks down with a slightly lengthy error message (see blow). The gist of the error seems to be that in the first case RDataFrame somehow manages to resolve the (sub)branches as RVec<int>
, but as soon as an alias is involved it seemingly is accessed as an RVec<ObjectID>
, which obviously does not have an index
field. I suppose this is expected behavior? Is it in any way possible to make aliases behave more like aliases in this case?
Full error message
```console input_line_67:2:67: error: no member named 'index' in 'ROOT::VecOps::RVec' auto lambda0 = [](ROOT::VecOps::RVec& var0){return var0.index ~~~~ ^ In file included from /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/input_line_9:15: In file included from /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/etc/dictpch/allHeaders.h:806: /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1452:97: error: no member named 'value' in 'ROOT::Internal::VecOps::RVecInlineStorageSize' class R__CLING_PTRCHECK(off) RVec : public RVecN<T, Internal::VecOps::RVecInlineStorageSize::value> { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ input_line_71:2:66: note: in instantiation of template class 'ROOT::VecOps::RVec' requested here auto lambda0 = [](ROOT::VecOps::RVec& var0){return var0.index ^ In file included from /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/input_line_9:15: In file included from /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/etc/dictpch/allHeaders.h:806: /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1453:76: error: no member named 'value' in 'ROOT::Internal::VecOps::RVecInlineStorageSize' using SuperClass = RVecN<T, Internal::VecOps::RVecInlineStorageSize::value>; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1522:38: error: no function template matches function template specialization 'IsSmall' friend bool ROOT::Detail::VecOps::IsSmall(const RVec &v); ^ /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1089:6: note: candidate template ignored: failed template argument deduction bool IsSmall(const ROOT::VecOps::RVec &v) ^ /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1522:38: error: friend declaration of 'IsSmall' does not match any declaration in namespace 'ROOT::Detail::VecOps' friend bool ROOT::Detail::VecOps::IsSmall(const RVec &v); ^ /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1089:6: note: candidate template ignored: failed template argument deduction bool IsSmall(const ROOT::VecOps::RVec &v) ^ /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1524:38: error: no function template matches function template specialization 'IsAdopting' friend bool ROOT::Detail::VecOps::IsAdopting(const RVec &v); ^ /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1095:6: note: candidate template ignored: failed template argument deduction bool IsAdopting(const ROOT::VecOps::RVec &v) ^ /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1524:38: error: friend declaration of 'IsAdopting' does not match any declaration in namespace 'ROOT::Detail::VecOps' friend bool ROOT::Detail::VecOps::IsAdopting(const RVec &v); ^ /tmp/tmadlener/spack-stage/spack-stage-root-6.26.04-mxi2b3znosaooegjxfathocnqbawwvm2/spack-build-mxi2b3z/include/ROOT/RVec.hxx:1095:6: note: candidate template ignored: failed template argument deduction bool IsAdopting(const ROOT::VecOps::RVec &v) ^ Traceback (most recent call last): File "reproducer.py", line 32, in df.Alias("ids", "ObjectIDs").Define("idx", "ids.index").Display(["idx"]).Print() cppyy.gbl.std.runtime_error: Template method resolution failed: ROOT::RDF::RInterface ROOT::RDF::RInterface::Define(basic_string_view<char,char_traits > name, basic_string_view<char,char_traits > expression) => runtime_error: RDataFrame: An error occurred during just-in-time compilation. The lines above might indicate the cause of the crash All RDF objects that have not run an event loop yet should be considered in an invalid state.ROOT::RDF::RInterfaceROOT::Detail::RDF::RLoopManager,void ROOT::RDF::RInterfaceROOT::Detail::RDF::RLoopManager,void::Define(basic_string_view<char,char_traits > name, basic_string_view<char,char_traits > expression) =>
runtime_error:
RDataFrame: An error occurred during just-in-time compilation. The lines above might indicate the cause of the crash
All RDF objects that have not run an event loop yet should be considered in an invalid state.
</details>