Description
Python boost-histogram and hist users are accustomed to UHI-style slicing, but when Boost::Histogram objects are templated from their sources by Cling and accessed through PyROOT/cppyy, they only have reflected C++ methods, no UHI methods. This can happen in a Python process like
>>> import ROOT
>>> ROOT.gInterpreter.AddIncludePath("-I/tmp/histogram/include") # Boost::Histogram header-only library
>>> ROOT.gInterpreter.AddIncludePath("-I/home/jpivarski/miniconda3/include") # other Boost headers
>>> ROOT.gInterpreter.Declare("#include \"boost/histogram.hpp\"")
True
>>> ROOT.boost.histogram.make_histogram # make histograms from the C++ templates
cppyy template proxy (internal)
These C++ Boost::Histograms can be used in RDataFrame's C++ code strings; Python boost-histograms can't. But Python boost-histograms have UHI-style slicing and C++ Boost::Histograms don't. This mismatch is a problem.
One potential solution would be to dynamically wrap the C++ Boost::Histogram object as a Python boost-histogram. I don't know how feasible that is (and it's possible to use the templates to make classes that have no equivalent in the Python boost-histogram), but if that's a better solution than the one I'm proposing here, this issue should be transferred to scikit-hep/boost-histogram.
For users, all that's required is to have the same UHI interface for both. Addressing just that sounds easier (but correct me if I'm wrong). PyROOT supports targeted Pythonizations, which can be added outside of ROOT (but presumably good ones will be adopted?), like this:
@pythonization("boost::histogram<", is_prefix=True)
def pythonize_boost_hist(bhist_class):
bhist_class.__getitem__ = ...
Presumably, the implementation of bhist_class.__getitem__
should call the same methods in the C++ Boost::Histogram that are already done in the Python boost-histogram. Maybe a duck-typed solution might even be possible?