Lambdas for "parallel" vectors

Hi,

I have

struct BinSearch {
  float phi_c, dphi_min, dphi_max;
  ...
};
...
bso = mh->MakeField<std::vector<BinSearch>>("bso");
bsn = mh->MakeField<std::vector<BinSearch>>("bsn");

The vectors are “parallel”, ie, they have the same number of elements for every event / entry. I was trying to define the difference and had trouble with the lambda versions, the string-based one works as expected, as TTree::Draw machinery does it.

   auto H = ROOT::RDF::Experimental::FromRNTuple("H", "SelHitIdcs.root");
   auto H0 = H.Define("Ddphi", [](float n, float o) { return n - o; }, {"bsn.dphi_max", "bso.dphi_max"});
   auto H1 = H.Define("Ddphi", [](BinSearch &n, BinSearch &o) { return n.dphi_max - o.dphi_max;}, {"bsn", "bso"});
   auto H2 = H.Define("Ddphi", "bsn.dphi_max - bso.dphi_max");

Expanding / plotting H0 returns N_events zeroes, H1 causes an unscheduled interruption, see below.

How is one supposed to write a lambda expression version of Define for this case?

Cheers,
Matevz

(gdb) bt
#0  0x00007ffff08f745e in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::size (this=0x0) at /usr/include/c++/13/bits/hashtable.h:648
#1  0x00007ffff08f6aeb in std::_Hashtable<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::find (this=0x0, __k="Ddphi") at /usr/include/c++/13/bits/hashtable.h:1677
#2  0x00007fffdb5e7dd7 in std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::find (this=0x0, __x="Ddphi") at /usr/include/c++/13/bits/unordered_map.h:887
#3  0x00007fffdb5e6103 in ROOT::Internal::RDF::RColumnRegister::ResolveAlias[abi:cxx11](std::basic_string_view<char, std::char_traits<char> >) const (this=0x7ffff765a010, alias="Ddphi") at /home/matevz/root-dev/dev-1/tree/dataframe/src/RDFColumnRegister.cxx:286
#4  0x00007fffdb619316 in ROOT::Internal::RDF::GetValidatedColumnNames (lm=..., nColumns=1,
    columns=std::vector of length 1, capacity 1 = {...}, colRegister=..., ds=0x0)
    at /home/matevz/root-dev/dev-1/tree/dataframe/src/RDFInterfaceUtils.cxx:903

Hi Matevz! I think @eguiraud or @vpadulan can most probably help you with this

Hi Matevz,

Thanks for the interesting post.
I tried to reproduce with this code *, but without success. What ROOT version are you using?

Cheers,
D

*

#include <ROOT/RDataFrame.hxx>
#include <ROOT/RNTupleImporter.hxx>
#include <ROOT/RNTupleDS.hxx>

// exec as root repro.C+ , to properly generate dictionaries...

struct BinSearch {
  float phi_c, dphi_min, dphi_max;
};

void createInput(std::string_view tree_fname)
{
   auto df = ROOT::RDataFrame(16);
   auto createBinSearch = [](){return BinSearch();};
   df.Define("bsn", createBinSearch)
     .Define("bso", createBinSearch)
     .Snapshot<BinSearch,BinSearch>("H",tree_fname, {"bsn","bso"});
}

void convertToRNtuple(std::string_view tree_fname, std::string_view rntuple_fname)
{
   auto importer = ROOT::Experimental::RNTupleImporter::Create(tree_fname, "H", rntuple_fname);
   importer->Import();
}

void testRDF(ROOT::RDataFrame &H)
{
   auto H0 = H.Define("Ddphi", [](float n, float o) { return n - o; }, {"bsn.dphi_max", "bso.dphi_max"});
   auto H1 = H.Define("Ddphi", [](BinSearch &n, BinSearch &o) { return n.dphi_max - o.dphi_max;}, {"bsn", "bso"});
   auto H2 = H.Define("Ddphi", "bsn.dphi_max - bso.dphi_max");
   std::cout << H0.Count().GetValue() << std::endl;
   std::cout << H1.Count().GetValue() << std::endl;
   std::cout << H2.Count().GetValue() << std::endl;
}

void repro()
{
   const auto tree_fname = "SelHitIdcs_ttree.root";
   const auto rntuple_fname = "SelHitIdcs.root";
   createInput(tree_fname);
   convertToRNtuple(tree_fname, rntuple_fname);

   std::cout << "Testing RDF From TTree..." << std::endl;
   auto ttree_df = ROOT::RDataFrame("H", tree_fname);
   testRDF(ttree_df);

   std::cout << "Testing RDF From RNtuple..." << std::endl;
   auto rntuple_df = ROOT::RDF::Experimental::FromRNTuple("H", rntuple_fname);
   testRDF(rntuple_df);
}

Thank you Danilo!

It’s something not too far off master, usually I’m not more than a month behind :slight_smile: Let me check:

commit 297dbdefc92d338b164b2fe86604b5582fd2e38f (HEAD -> master, origin/master, origin/HEAD)
Date:   Thu Sep 21 15:53:40 2023 +0200

So you’re saying this works with master? I can recheck and re-post with more details if I still have trouble.

Cheers,
Matevz

Hi Matevz,

That is with the master of today :slight_smile: and I hope it addresses your enquiry. If you can, try with a more recent commit and then we can rediscuss if needed.
Thanks for the flexibility.

Cheers,
D

Hi Danilo,

After updating, both lambda versions behave the same, as H0 case initially. I’ll try to modify your example to see if I can reproduce the issue there, note that my fields are std::vector. Otherwise I’ll try to pack up my data-formats and a ROOT file.

Cheers,
Matevz

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