apache / fury

A blazingly fast multi-language serialization framework powered by JIT and zero-copy.
https://fury.apache.org/
Apache License 2.0
3.11k stars 248 forks source link

`radial_scale` parameter of `actor.odf_slicer` has some issues #1941

Closed zp1008611 closed 1 week ago

zp1008611 commented 1 week ago

Search before asking

Version

dipy 1.9.0 fury 0.11.0

Component(s)

Python

Minimal reproduce step

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,)

What did you expect to see?

In the attached code, the last line uses actor.odf_slicer. When radial_scale set to False, it does not result in an error.

What did you see instead?

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.

error png

image

Anything Else?

No response

Are you willing to submit a PR?

chaokunyang commented 1 week ago

Seems you reported to the wrong repo. Apache Fury is a serialization library

zp1008611 commented 1 week ago

I previously reported an issue in the dipy repository,but they said it's a problem with the fury module, as dipy's visualization embeds the fury module.

---Original--- From: "Shawn @.> Date: Mon, Nov 11, 2024 12:21 PM To: @.>; Cc: @.**@.>; Subject: Re: [apache/fury] radial_scale parameter of actor.odf_slicer hassome issues (Issue #1941)

Seems you reported to the wrong repo. Apache Fury is a serialization library

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

zp1008611 commented 1 week ago

My apologies, I realized I've approached the wrong repository.

---Original--- From: "Shawn @.> Date: Mon, Nov 11, 2024 12:21 PM To: @.>; Cc: @.**@.>; Subject: Re: [apache/fury] radial_scale parameter of actor.odf_slicer hassome issues (Issue #1941)

Seems you reported to the wrong repo. Apache Fury is a serialization library

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

chaokunyang commented 1 week ago

It's OK, so I'll close this issue now