Problems with OnPartialResultSlot in new ROOT version 6.32.02

The following code (almost dummy for this example) was working in previous versions of ROOT (6.30.02), but not in a new one (6.32.02). Anybody knows what is going on ? Has the call tp OnPartialResultsSlot been changed? Should the registration of MyPrintEntries proceeed differently ?

Thanks, Juan

    def ShowEvolution(self, pos):
        # Declare function for printout (just once)
        if not ROOT.gROOT.GetGlobalFunction("MyPrintEntries"):
            ROOT.gInterpreter.Declare(
            """
            void MyPrintEntries(unsigned int iSlot, unsigned long long& iEvent){
                return;
            }
            """ 
            )

        # Set printout per file every nDump processed events
        nDump = 10000
        self.df[pos].Count().OnPartialResultSlot(nDump,ROOT.MyPrintEntries)

The error is:

    self.df[pos].Count().OnPartialResultSlot(nDump,ROOT.MyPrintEntries)
NotImplementedError: ROOT::RDF::RResultPtr<ULong64_t>& ROOT::RDF::RResultPtr<ULong64_t>::OnPartialResultSlot(ULong64_t everyNEvents, function<void(unsigned int,ULong64_t&)> callback) =>
    NotImplementedError: could not convert argument 2 (this method cannot (yet) be called)

Dear Juan,

Thanks for the interesting post and welcome to the ROOT Community!
This seems to be an effect of the new version of cppyy, the interoperability engine behind PyROOT. I add in the loop our expert, @jonas .

Cheers,
D

Dear @Juan_Alcaraz,

I could reproduce this problem, with a simple reproducer. I opened an issue on GitHub so we don’t forget to fix it.

In the meantime, I can suggest you an alternative implementation, where the callback function is defined as a lambda function and passed around on the C++ side:

import ROOT

ROOT.gInterpreter.Declare(
"""
template<typename T>
ROOT::RDF::RResultPtr<T> &MyOnPartialResultSlot(
    ROOT::RDF::RResultPtr<T> &resultPtr,
    ULong64_t everyNEvents)
{
   auto myPrintEntries = [](unsigned int iSlot,
                            unsigned long long& iEvent) -> void
   {
      std::cout << "iEvent: " << iEvent << std::endl;
   };

   return resultPtr.OnPartialResultSlot(everyNEvents, myPrintEntries);
}
""" 
)

df = ROOT.RDataFrame(100).Define("x", "gRandom->Rndm()")

n_dump = 1

count = ROOT.MyOnPartialResultSlot(df.Count(), n_dump)

print(count.GetValue())

I hope this is good enough for now! This solution is also backwards compatible with older ROOT versions.

Cheers,
Jonas

Thanks Jonas. Also for the fix, which works fine.

Best, Juan