77
77
def _get_cpp_type_from_numpy_type (dtype ):
78
78
cpptypes = {"i2" : "Short_t" , "u2" : "UShort_t" , "i4" : "int" , "u4" : "unsigned int" , "i8" : "Long64_t" , "u8" : "ULong64_t" , "f4" : "float" , "f8" : "double" , "b1" : "bool" }
79
79
80
- if not dtype in cpptypes :
80
+ if dtype not in cpptypes :
81
81
raise RuntimeError ("Object not convertible: Python object has unknown data-type '" + dtype + "'." )
82
82
83
83
return cpptypes [dtype ]
@@ -93,10 +93,11 @@ def _AsRVec(arr):
93
93
This function returns an RVec which adopts the memory of the given
94
94
PyObject. The RVec takes the data pointer and the size from the array
95
95
interface dictionary.
96
+ Note that for arrays of strings, the input strings are copied into the RVec.
96
97
"""
97
98
import ROOT
98
99
import math
99
- import platform
100
+ import numpy as np
100
101
101
102
# Get array interface of object
102
103
interface = arr .__array_interface__
@@ -110,17 +111,28 @@ def _AsRVec(arr):
110
111
111
112
# Get the typestring and properties thereof
112
113
typestr = interface ["typestr" ]
114
+ dtype = typestr [1 :]
115
+
116
+ # Construct an RVec of strings
117
+ if dtype == "O" or dtype .startswith ("U" ):
118
+ underlying_object_types = {type (elem ) for elem in arr }
119
+ if len (underlying_object_types ) > 1 :
120
+ raise TypeError ("All elements in the numpy array must be of the same type. Found types: {}" .format (underlying_object_types ))
121
+
122
+ if underlying_object_types and underlying_object_types .pop () in [str , np .str_ ]:
123
+ return ROOT .VecOps .RVec ["std::string" ](arr )
124
+ else :
125
+ raise TypeError ("Cannot create an RVec from a numpy array of data type object." )
126
+
113
127
if len (typestr ) != 3 :
114
128
raise RuntimeError (
115
129
"Object not convertible: __array_interface__['typestr'] returned '"
116
130
+ typestr
117
131
+ "' with invalid length unequal 3."
118
132
)
119
-
120
- dtype = typestr [1 :]
121
- cppdtype = _get_cpp_type_from_numpy_type (dtype )
122
-
133
+
123
134
# Construct an RVec of the correct data-type
135
+ cppdtype = _get_cpp_type_from_numpy_type (dtype )
124
136
out = ROOT .VecOps .RVec [cppdtype ](ROOT .module .cppyy .ll .reinterpret_cast [f"{ cppdtype } *" ](data ), size )
125
137
126
138
# Bind pyobject holding adopted memory to the RVec
0 commit comments