PMEAL / porespy

A set of tools for characterizing and analying 3D images of porous materials
https://porespy.org
MIT License
303 stars 98 forks source link

Integer overflow in _radial_profile in metrics\__funcs__.py #237

Closed kleinerELM closed 3 years ago

kleinerELM commented 4 years ago

I am just trying to use porespy and stumbled across an integer overflow error:

File "...\porespy\metrics__funcs__.py

", line 332, in _radial_profile

radial_sum[i] = np.sum(autocorr[mask])/np.sum(mask)

OverflowError: Python int too large to convert to C long

It seems this is easily fixable changing line 325 in .\porespy\metrics__funcs__.py from radial_sum = np.zeros_like(bins) to radial_sum = np.zeros_like(bins, np.int64)

The error occured following this example of the documentation using an real data image (8-bit TIFF, 1024x880):

im = cv2.imread( settings["referenceFilePath"], 0 )
data = ps.metrics.two_point_correlation_fft(im)
fig = plt.plot(*data, 'bo-')
plt.ylabel('probability')
plt.xlabel('correlation length [voxels]')
plt.show()
ma-sadeghi commented 4 years ago

Hi @kleinerELM, can you share your image by any chance so I can reproduce the bug?

kleinerELM commented 4 years ago

Sorry I forgot to attach it:

C2-C3S 28d cryoBIB_004-cut.zip

ma-sadeghi commented 4 years ago

I was able to run your script, except that I read the image using imageio library via

import imageio
im = imageio.imread("C2-C3S 28d cryoBIB_004-cut.tif")

which I don't think should make a difference.

What's your OS + Python/porespy version?

kleinerELM commented 4 years ago

I was using porespy 1.2.0, freshly installed using

pip install porespy

Enviornment: Win 10 Pro 1909 Python 3.7.2 numpy 1.15.4

Errormessage (stripped full folder paths):

Traceback (most recent call last):
  File ".\porespy_test.py", line 68, in <module>
    data = ps.metrics.two_point_correlation_fft(im)
  File ".\porespy\metrics\__funcs__.py", line 370, in two_point_correlation_fft
    tpcf = _radial_profile(autoc, r_max=np.min(hls))
  File ".\porespy\metrics\__funcs__.py", line 329, in _radial_profile
    radial_sum[i] = np.sum(autocorr[mask])/np.sum(mask)
OverflowError: Python int too large to convert to C long

And ideed, the value 9615212611.875 is assigned to the radial_sum[i] at one point. And since the radial_sum list only contains int32e (as the array bins, which dtype is used to initiate radial_sum), the value exceeds the data type. And as alread said, I was able to fix the issue, when forcing 64 bit integers for radial_sum.

The error persists if I am using imageio to open the image instead of cv2.

ma-sadeghi commented 4 years ago

I see. It's because on Linux. According to this stackoverflow thread, the default numpy.int_ is C long, but C long is int32 even Win64.

Thank you for reporting this. We'll see what we can do to force int64 as the default int type.

kleinerELM commented 4 years ago

Okay, thanks for your fast response and the nice libary!