Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dipy has a problem calling fury #942

Open
zp1008611 opened this issue Nov 8, 2024 · 1 comment
Open

dipy has a problem calling fury #942

zp1008611 opened this issue Nov 8, 2024 · 1 comment

Comments

@zp1008611
Copy link

Description

When I use dipy, I found that the radial_scale parameter of actor.odf_slicer has some issues.

In the attached code, the last line uses actor.odf_slicer. When radial_scale is set to True, it doesn't raise an error, but when set to False, it does result in an error. And the member of dipy said This is a FURY issue.

Way to reproduce

Code example:

# %%
import numpy as np 
from dipy.sims.voxel import multi_tensor, multi_tensor_odf 
from dipy.data import get_sphere 
from dipy.core.sphere import disperse_charges, Sphere, HemiSphere 
from dipy.core.gradients import gradient_table 
from fury import window, actor 
from IPython.core.display import Image 
from PIL import Image as PILImage 

import os

# %%
# helper functions for visualization 
WINDOW_SIZE = (400,400)
SAVEIM_FOLDER = "images"
if not os.path.exists(SAVEIM_FOLDER): 
    os.mkdir(SAVEIM_FOLDER)
def screenshot_animated_sf(sf, sphere, rot=True, norm=True, scale=True, title='Modeling', theta_step=30):

    """
        Render a spherical function to file. Returns path to image.
    """
    scene = window.Scene() 
    scene.background(window.colors.white)
    sf_actor = actor.odf_slicer(sf[None, None, None,:], 
        sphere=sphere, colormap='jet', 
        norm=norm, radial_scale=scale)
    if rot: 
        scene.add(sf_actor)
        sf_actor.Rotatex(90)
    n_frames = 360//theta_step 
    images=[] 
    for i in np.arange(n_frames): 
        sf_actor.Rotatex(theta_step)
        scene.reset_clipping_range() 
        images.append(PILImage.fromarray(window.snapshot(scene, size=WINDOW_SIZE)))

    frame_duration = 15000 // theta_step
    filename = os.path.join(SAVEIM_FOLDER, '{0}.gif'.format(title))
    images[0].save(filename, save_all=True, append_images=images[1:], duration=frame_duration, optimize=False, loop=0)
    scene.clear()
    return filename

def screenshot_gradients(sph_gtab, title='Modeling'):
    scene = window.Scene()
    scene.background(window.colors.white)
    scene.add(actor.point(sph_gtab.vertices, window.colors.green, point_radius=0.05))
    outfile = os.path.join(SAVEIM_FOLDER, '{0}.png'.format(title))
    window.snapshot(scene, size=WINDOW_SIZE, fname=outfile)
    scene.clear()
    return outfile

# %% [markdown]
# ### Part 1 - Apparent diffusion coefficient and spherical harmonics Generating a gradient table

# %%
n_pts = 64
bvalue = 1000
theta = np.pi * np.random.rand(n_pts)
phi = 2 * np.pi * np.random.rand(n_pts)
hsph_initial = HemiSphere(theta=theta, phi=phi)
hsph_updated, potential = disperse_charges(hsph_initial, 5000)

vertices = hsph_updated.vertices
values = np.ones(vertices.shape[0])
bvecs = np.vstack((vertices))
bvals = np.hstack((bvalue * values)) 
#add some b=0 bvals/bvecs
bvecs = np.insert(bvecs, (0, bvecs.shape[0]), np.array([0, 0, 0]), axis=0)
bvals = np.insert(bvals, (0, bvals.shape[0]), 0)

gtab = gradient_table(bvals, bvecs)
sph_gtab = Sphere(xyz=np.vstack((vertices, -vertices)))
print('bvecs:\n', bvecs)
print('bvals:\n', bvals)

# %%
image = screenshot_gradients(sph_gtab, title='Example directions')
Image(filename=image)

# %% [markdown]
# #### Playing with different single and multi-tensor signal generation
# 

# %%
S0 = 100
SNR = 100
N = 2 # change this value to try other number of fibers
if N == 1:
    mevals = np.array([[0.0015, 0.0004, 0.0004]])
    angles = [(0, 0)]
    fractions = [100]
elif N == 2:
    separation_angle = 90 # play with this parameter to change the angle between fibers
    mevals = np.array([[0.0015, 0.0004, 0.0004],
                        [0.0015, 0.0004, 0.0004]])
    angles = [(0, 0), (separation_angle, 0)]
    fractions = [50, 50]
elif N == 3:
    mevals = np.array([[0.0015, 0.0004, 0.0004],
                        [0.0004, 0.0015, 0.0004], 
                        [0.0004, 0.0004, 0.0015]])
    angles = [(0, 0), (90, 0), (0, 90)]
    fractions = [33, 33, 34]
else:
    raise ValueError('Invalid number of fibers.')
signal, sticks = multi_tensor(gtab, mevals, S0 = S0, angles = angles,
                               fractions = fractions, snr = SNR)
print(signal)

# %%
# we generate an antipodally symmetric spherical function from our signal
signal_sph = np.zeros(vertices.shape[0]*2)
signal_sph[0:vertices.shape[0]] = signal[1:-1]
signal_sph[vertices.shape[0]:] = signal[1:-1]

actor.odf_slicer(signal_sph[None, None, None,:], sphere=sph_gtab, colormap='jet', norm=False, radial_scale=False,)

error png

image

python version

python 3.9.10

dipy version

1.9.0

fury version

0.11.0

@skoudoro
Copy link
Contributor

Hi @zp1008611,

Thank you for this. This is due to the new VTK.

to fix this issue, downgrade your VTK version and make sure that vtk<=9.3.1

We will release FURY to make sure this is the correct vtk version

Thank for your feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants