import numpy as np
with open("binary_stuff.dat", "rb") as f:
d = np.fromfile(f, dtype=">f4", count=1024)
# verify no NaNs, etc:
assert not np.any(np.isnan(d))
print(f"(min, max): ({d.min()}, {d.max()})")
# which returns:
# -769.35077, 142235120000.0
Note: the datafile is big endian, while my computer is little endian.
I had been trying to add this to a VTK dataset using something like this:
a = vtk.vtkFloatArray()
a.SetNumberOfComponents(1)
a.SetNumberOfTuples(d.size)
a.SetName("Weirdness")
for s in d.ravel():
a.InsertNextValue(s)
print(a.GetValueRange())
(-1.9957235928163046e+38, 1.3434351138279377e+38)
# I also tried:
# a = numpy_to_vtk(d.ravel())
I’m sure whatever it is that is messing me up, is likely simple … I hope.
It’s because you call SetNumberOfTuples() before calling InsertNextValue().
Calling SetNumberOfTuples(n) will set the size of the array to n. All n values in the array will be left uninitialized. Then, InsertNextValue(x) will add x to the end of the array, giving an array size of n+1.
Here are two simple ways to fix this:
remove SetNumberOfTuples(), or
use for i,s in enumerate(d.ravel()): a.SetValue(i, s)
Probably because d.ravel() is a temporary array. The purpose of numpy_to_vtk() is to create VTK array whose contents are just a pointer to the internal buffer of the numpy array. So if the numpy array is deleted or resized, then the VTK array ends up with a dangling pointer.
It should work if you do this, which will force VTK to make a copy of the array memory:
rexthor@workstation:~ $ python3
Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> from vtk.util.numpy_support import numpy_to_vtk
>>> b = np.array([1, 2], dtype=np.float32)
>>> a = numpy_to_vtk(b)
>>> a.GetValue(0)
1.0
>>> a.GetValue(1)
2.0
>>> a.GetValueRange()
(1.0, 2.0)
However, when you throw big-endian stuff into the mix:
import struct
buffer = struct.pack(">ff", 1, 2)
a = np.frombuffer(buffer, dtype=">f4")
c = numpy_to_vtk(a)
c.GetValueRange()
(8.96831017167883e-44, 4.600602988224807e-41)