Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions .github/workflows/docbuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12"]
python-version: ["3.13"]

steps:
- name: Checkout repo
Expand All @@ -33,13 +33,16 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install .[all]
sudo apt-get install -y xvfb
sudo apt-get install -y \
libgl1 \
libglx-mesa0 \
libegl1 \
libgl1-mesa-dri \
libvulkan1 \
mesa-vulkan-drivers \
vulkan-tools
- name: Build docs
env:
XVFB: 1
DISPLAY: :99
run: |
Xvfb :99 -screen 0 1280x1024x24 &
cd docs
make html
- name: Upload docs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly_anisotropic_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.12"]
python-version: ["3.13"]

steps:
- name: Checkout repo
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly_basic_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.12"]
python-version: ["3.13"]

steps:
- name: Checkout repo
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/nightly_custom_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.12"]
python-version: ["3.13"]

steps:
- name: Checkout repo
Expand All @@ -28,10 +28,17 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install .[dev,fury,afqbrowser,nn]
sudo apt-get install -y \
libgl1 \
libglx-mesa0 \
libegl1 \
libgl1-mesa-dri \
libvulkan1 \
mesa-vulkan-drivers \
vulkan-tools
- name: Lint
run: |
flake8 --ignore N802,N806,W503 --select W504 `find . -name \*.py | grep -v setup.py | grep -v version.py | grep -v __init__.py | grep -v /docs/`
- name: Test
run: |
export TEST_WITH_XVFB=true
cd && mkdir for_test && cd for_test && pytest --pyargs AFQ --cov-report term-missing --cov=AFQ -m "nightly_custom" --durations=0
2 changes: 1 addition & 1 deletion .github/workflows/nightly_reco80_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.12"]
python-version: ["3.13"]

steps:
- name: Checkout repo
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly_reco_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.12"]
python-version: ["3.13"]

steps:
- name: Checkout repo
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.12"]
python-version: ["3.13"]

steps:
- name: Checkout repo
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.10", "3.11", "3.12"]
python-version: ["3.11", "3.12", "3.13"]
nibabel-pre: [true, false]

steps:
Expand Down
44 changes: 44 additions & 0 deletions AFQ/_fixes.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import logging
import math
import tempfile
from math import radians

import numpy as np
from dipy.data import default_sphere
from dipy.reconst.gqi import squared_radial_component
from dipy.tracking.streamline import set_number_of_points
from PIL import Image
from scipy.linalg import blas, pinvh
from scipy.special import gammaln, lpmv
from tqdm import tqdm
Expand Down Expand Up @@ -238,3 +241,44 @@ def gaussian_weights(bundle, n_points=100, return_mahalnobis=False, stat=np.mean
weights = 1 / weights
# Normalize before returning, so that the weights in each node sum to 1:
return weights / np.sum(weights, 0)


def make_gif(show_m, out_path, n_frames=36, az_ang=-10):
"""
Make a video from a Fury Show Manager.

Parameters
----------
show_m : Fury Show Manager
The Fury Show Manager to use for rendering.

out_path : str
The name of the output file.

n_frames : int
The number of frames to render.
Default: 36

az_ang : float
The angle to rotate the camera around the
z-axis for each frame, in degrees.
Default: -10
"""
video = []

show_m.render()
show_m.window.draw()

with tempfile.TemporaryDirectory() as tmp_dir:
for ii in tqdm(range(n_frames), desc="Generating GIF"):
frame_fname = f"{tmp_dir}/{ii}.png"
show_m.screens[0].controller.rotate((radians(az_ang), 0), None)
show_m.render()
show_m.window.draw()
show_m.snapshot(frame_fname)
video.append(frame_fname)

video = [Image.open(frame) for frame in video]
video[0].save(
out_path, save_all=True, append_images=video[1:], duration=300, loop=1
)
20 changes: 8 additions & 12 deletions AFQ/api/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,6 @@ def group_montage(self, bundle_name, size, view, direc, slice_pos=None):

t1_dict = self.export("t1_masked", collapse=False)
viz_backend_dict = self.export("viz_backend", collapse=False)
b0_backend_dict = self.export("b0", collapse=False)
dwi_affine_dict = self.export("dwi_affine", collapse=False)
bundles_dict = self.export("bundles", collapse=False)
best_scalar_dict = self.export(best_scalar, collapse=False)
Expand All @@ -847,7 +846,6 @@ def group_montage(self, bundle_name, size, view, direc, slice_pos=None):
this_sub = self.valid_sub_list[ii]
this_ses = self.valid_ses_list[ii]
viz_backend = viz_backend_dict[this_sub][this_ses]
b0 = b0_backend_dict[this_sub][this_ses]
t1 = nib.load(t1_dict[this_sub][this_ses])
dwi_affine = dwi_affine_dict[this_sub][this_ses]
bundles = bundles_dict[this_sub][this_ses]
Expand Down Expand Up @@ -913,17 +911,15 @@ def group_montage(self, bundle_name, size, view, direc, slice_pos=None):

pio.kaleido.scope._shutdown_kaleido()
else:
from dipy.viz import window

direc = np.fromiter(eye.values(), dtype=int)
data_shape = np.asarray(nib.load(b0).get_fdata().shape)
figure.set_camera(
position=direc * data_shape,
focal_point=data_shape // 2,
view_up=(0, 0, 1),
from fury import window

from AFQ.viz.fury_backend import scene_rotate_forward

show_m = window.ShowManager(
scene=figure, window_type="offscreen", size=(600, 600)
)
figure.zoom(0.5)
window.snapshot(figure, fname=this_fname, size=(600, 600))
scene_rotate_forward(show_m, figure)
show_m.snapshot(this_fname)

def _save_file(curr_img, curr_file_num):
save_path = op.abspath(
Expand Down
19 changes: 8 additions & 11 deletions AFQ/api/participant.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from time import time

import nibabel as nib
import numpy as np
from PIL import Image, ImageDraw, ImageFont
from tqdm import tqdm

Expand Down Expand Up @@ -317,17 +316,15 @@ def participant_montage(self, images_per_row=2):

pio.kaleido.scope._shutdown_kaleido()
else:
from dipy.viz import window

direc = np.fromiter(eye.values(), dtype=int)
data_shape = np.asarray(nib.load(self.export("b0")).get_fdata().shape)
figure.set_camera(
position=direc * data_shape,
focal_point=data_shape // 2,
view_up=(0, 0, 1),
from fury import window

from AFQ.viz.fury_backend import scene_rotate_forward

show_m = window.ShowManager(
scene=figure, window_type="offscreen", size=(600, 600)
)
figure.zoom(0.5)
window.snapshot(figure, fname=this_fname, size=(600, 600))
scene_rotate_forward(show_m, figure)
show_m.snapshot(this_fname)

def _save_file(curr_img):
save_path = op.abspath(
Expand Down
14 changes: 1 addition & 13 deletions AFQ/tasks/viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,34 +385,22 @@ def plot_tract_profiles(base_fname, output_dir, scalars, segmentation_imap):


@immlib.calc("viz_backend")
def init_viz_backend(viz_backend_spec="plotly_no_gif", virtual_frame_buffer=False):
def init_viz_backend(viz_backend_spec="plotly_no_gif"):
"""
An instance of the `AFQ.viz.utils.viz_backend` class.

Parameters
----------
virtual_frame_buffer : bool, optional
Whether to use a virtual frame buffer. This is if
generating GIFs in a headless environment.
Default: False
viz_backend_spec : str, optional
Which visualization backend to use.
See Visualization Backends page in documentation for details
https://tractometry.org/pyAFQ/reference/viz_backend.html
One of {"fury", "plotly", "plotly_no_gif"}.
Default: "plotly_no_gif"
"""
if not isinstance(virtual_frame_buffer, bool):
raise TypeError("virtual_frame_buffer must be a bool")
if "fury" not in viz_backend_spec and "plotly" not in viz_backend_spec:
raise TypeError("viz_backend_spec must contain either 'fury' or 'plotly'")

if virtual_frame_buffer:
from xvfbwrapper import Xvfb

vdisplay = Xvfb(width=1280, height=1280)
vdisplay.start()

return Viz(backend=viz_backend_spec.lower())


Expand Down
2 changes: 0 additions & 2 deletions AFQ/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import toml
from dipy.io.streamline import load_tractogram
from dipy.segment.metric import mdf
from dipy.testing.decorators import xvfb_it
from pandas.testing import assert_series_equal
from pcollections._lazy import LazyError

Expand Down Expand Up @@ -272,7 +271,6 @@ def test_AFQ_no_derivs():


@pytest.mark.nightly_custom
@xvfb_it
def test_AFQ_fury():
tmpdir = tempfile.TemporaryDirectory()
bids_path = op.join(tmpdir.name, "stanford_hardi")
Expand Down
Loading
Loading