Closed cookpa closed 4 months ago
That call is actually OK, I think. If interp_type
is an int it gets handled:
interpolator_oldoptions = ("linear", "nearestNeighbor", "gaussian", "cosineWindowedSinc", "bSpline")
if isinstance(interp_type, int):
interpolator = interpolator_oldoptions[interp_type]
Otherwise, I agree that there should be a way to catch errors on library calls. Perhaps when calling get_lib_fn
we actually return a call to the lib fn that is wrapped in a try-catch block.
But yes that test looks incorrect:
import ants
import numpy as np
img = ants.image_read(ants.get_data('r16'))
imglist = [img.clone(),img.clone(),img.clone()]
s = [65]*img.dimension
mask2 = ants.from_numpy(np.random.randn(*s))
mask2 = mask2 > mask2.mean()
imgmat = ants.images_to_matrix(imglist, mask=mask2)
print(imgmat.sum()) # equals 0, but shouldnt I guess?
And tracing it more specifically:
import ants
import numpy as np
img = ants.image_read(ants.get_data('r16'))
s = [65]*img.dimension
mask = ants.from_numpy(np.random.randn(*s))
mask = mask > mask.mean()
img2 = ants.resample_image_to_target(img, mask, 2)
print(img2.sum()) # all zero
Thanks! Can't fix now but can look at it later
No prob.. think it has to do with spacing. I removed that listfunc
thing though so maybe that will fix the error at least... it's like a function within a function trying to access the mask which isn't really in the scope of the inner function.
One more thought before I have to run, should this
be a clone of fixed, rather than moving? Since the output will be written to an image of dimension fixed. Not sure if it matters, seems like it would have been noticed by now if so.
Just worried about these intermittent access violations in light of issues like #590
Answering my own question, it's fine to have
warpedmovout = moving.clone(output_pixel_type)
because the pointer will be reassigned to point to the output image created inside the C++ code, and it doesn't matter if the output image has more or less pixels.
I also noticed resample_image_to_target (and ants.apply_transforms) will reset the output data type to the target type. So
img = ants.image_read(ants.get_data('r16')) mask = ants.image_clone( img > img.mean() ) mask ANTsImage Pixel Type : unsigned char (uint8) Components : 1 Dimensions : (256, 256) Spacing : (1.0, 1.0) Origin : (0.0, 0.0) Direction : [1. 0. 0. 1.]
x = ants.resample_image_to_target(img, mask, 'linear') x ANTsImage Pixel Type : unsigned char (uint8) Components : 1 Dimensions : (256, 256) Spacing : (1.0, 1.0) Origin : (0.0, 0.0) Direction : [1. 0. 0. 1.]
I think this shouldn't cause the memory error because the values should get cast to the matrix type, but it is different to how the CLI behaves. Needs documenting if nothing else
Fixed by #642
I looked again at the code vs the main apply_transforms, and one thing resample doesn't do is clone the input images to float, so I changed this in #647
Tracking down the Windows access exceptions
This line is implicated
https://github.com/ANTsX/ANTsPy/blob/cd2a4acafc9fa38ea435de8fb9160522f024f242/ants/utils/matrix_image.py#L151
This call looks wrong to me, it doesn't match the function
https://github.com/ANTsX/ANTsPy/blob/cd2a4acafc9fa38ea435de8fb9160522f024f242/ants/ops/resample_image.py#L79
also within resample_image.py, I don't think this will work
https://github.com/ANTsX/ANTsPy/blob/cd2a4acafc9fa38ea435de8fb9160522f024f242/ants/ops/resample_image.py#L157
So why doesn't this fail everywhere? It's a problem I've come across before, where library functions are called and passed references to clones of the input. If the library function doesn't write to its output image for any reason, the cloned input is returned unmodified. I'd appreciate any ideas of how to address this problem systematically, because I think it can be the source of many quiet bugs.