root
root copied to clipboard
std::function conversion not working with class in nested namespace
Check duplicate issues.
- [ ] Checked for duplicates
Description
While trying to use the RNTupleImporter::SetFieldModifier
feature, I stumbled upon the following error:
input_line_71:2:19: error: unknown type name 'RFieldBase'
void fptr_wrap1(RFieldBase& arg0) {
^
Traceback (most recent call last):
File "/Users/vpadulan/Projects/rootcode/rntuple-importer-set-low-float-precision/repro_setfieldmodifier.py", line 55, in <module>
raise SystemExit(main())
^^^^^^
File "/Users/vpadulan/Projects/rootcode/rntuple-importer-set-low-float-precision/repro_setfieldmodifier.py", line 50, in main
importer.SetFieldModifier(low_precision_modifier)
TypeError: void ROOT::Experimental::RNTupleImporter::SetFieldModifier(ROOT::Experimental::RNTupleImporter::FieldModifier_t modifier) =>
TypeError: could not convert argument 1
The signature is here with FieldModifier_t being defined within the class here. It looks like the automatic conversion from Python function pointer to std::function is not working in this case, note that RFieldBase
should be ROOT::Experimental::RFieldBase
but the fully-qualified name is stripped down to the class name only. I am sure it could be simplified, but for now see the attached reproducer which shows the error with RNTupleImporter.
Reproducer
import ROOT
import numpy
import os
class DatasetContext:
input_file = "input_ttree.root"
dataset_name = "Events"
output_file = "output_rntuple.root"
def __init__(self):
with ROOT.TFile(self.input_file, "RECREATE") as f:
main_tree = ROOT.TTree(self.dataset_name, self.dataset_name)
x = numpy.array([0], dtype=numpy.double)
y = numpy.array([0], dtype=numpy.double)
main_tree.Branch("x", x, "x/D")
main_tree.Branch("y", y, "y/D")
x[0] = 11.
y[0] = 22.
main_tree.Fill()
x[0] = 33.
y[0] = 44.
main_tree.Fill()
x[0] = 55.
y[0] = 66.
main_tree.Fill()
main_tree.Write()
def __enter__(self):
return self
def __exit__(self, *_):
os.remove(self.input_file)
def low_precision_modifier(field: ROOT.Experimental.RFieldBase) -> None:
if field.GetFieldName() == "x":
field.SetColumnRepresentatives(
[[ROOT.Experimental.EColumnType.kReal16]])
def main() -> None:
with DatasetContext() as dataset:
importer = ROOT.Experimental.RNTupleImporter.Create(
dataset.input_file, dataset.dataset_name, dataset.output_file)
importer.SetFieldModifier(low_precision_modifier)
importer.Import()
if __name__ == "__main__":
raise SystemExit(main())
ROOT version
Any
Installation method
Any
Operating system
Any
Additional context
No response