How to handle "ROOT._Bit_reference objects"

Dear ROOT developers,

I am using the brand new RDataFrame.AsNumpy() routine to convert a TTree to a numpy array. Certain branches now contain entries like the following:

<ROOT._Bit_reference object at 0x55aeff135b20>

Is it possible to convert these to Python accessible types (doubles, ints, etc.)?

Cheers,
Ben


ROOT Version: 6.18.00
Platform: Linux Mint


Hi!

Could you tell me which C++ type the branch has? You can find that out via your_tree->Print(), e.g., directly in the ROOT prompt. A bit reference in PyROOT hints to some pointer-like type.

A quick fix for now would be the following:

df = ROOT.RDataFrame(...)
df = df.Define("new_x", "int(x)") # Convert x of your C++ data-type to int with a C++ cast
x = df.AsNumpy(["new_x"]) # Now, you read x for sure as int

Best
Stefan

Edit:

You can get the type even simpler: https://root.cern/doc/master/classROOT_1_1RDF_1_1RInterface.html#ad3ccd813d9fed014ae6a080411c5b5a8

It works like that:

print(df.GetColumnType("x"))

_Bit_reference is the return type of std::vector<bool>::operator[](int). These are normally pythonized in PyROOT to return boolean types instead.

Thanks, I was wrong! It’s a boolean and not a pointer. Here a minimal reproducer:

import ROOT
df = ROOT.ROOT.RDataFrame(1).Define("x", "(bool)true")
x = df.AsNumpy(["x"])
print(x)
{'x': numpy.array([<ROOT._Bit_reference object at 0x2507710>], dtype=object)}

Alright, so your branch has a bool as data-type. The solution (for now) is simply casting the branch to another fundamental type such as int. This may also increase the throughput for the read-out!

A little bit more background on this issue: The C++ container for an array of bool is a std::vector<bool>. As you can see here, the container is specialized so that you can story 8 booleans in 1 byte. That’s nice (memory-wise) but is horrible for memory adoption since a numpy.array(dtype="bool") has one boolean per byte. So unfortunately we have to copy to go from C++ to Python. Or you cast the boolean on the C++ side to an integer :wink:

Thanks for the feedback! How unfortunate that I need to typecast, but I’ll try it.

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