Skip to content

Commit

Permalink
Merge pull request #1079 from CHrlS98/grid-intersections
Browse files Browse the repository at this point in the history
[DOC] Add documentation for grid_intersections
  • Loading branch information
arnaudbore authored Dec 16, 2024
2 parents 87b5a30 + 06c9a77 commit a5b490c
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 33 deletions.
5 changes: 0 additions & 5 deletions docs/source/fake_files/grid_intersections.py

This file was deleted.

5 changes: 5 additions & 0 deletions docs/source/fake_files/voxel_boundary_intersection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-


def subdivide_streamlines_at_voxel_faces():
pass
4 changes: 2 additions & 2 deletions docs/source/modules/scilpy.tractanalysis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ scilpy.tractanalysis.features module
:show-inheritance:


scilpy.tractanalysis.grid\_intersections module
scilpy.tractanalysis.voxel\_boundary\_intersection module
------------------------------------------------------

.. automodule:: scilpy.tractanalysis.grid_intersections
.. automodule:: scilpy.tractanalysis.voxel_boundary_intersection
:members:
:undoc-members:
:show-inheritance:
Expand Down
12 changes: 7 additions & 5 deletions scilpy/tractanalysis/afd_along_streamlines.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from scipy.special import lpn

from scilpy.reconst.utils import find_order_from_nb_coeff
from scilpy.tractanalysis.grid_intersections import grid_intersections
from scilpy.tractanalysis.voxel_boundary_intersection import\
subdivide_streamlines_at_voxel_faces


def afd_map_along_streamlines(sft, fodf, fodf_basis, length_weighting,
Expand Down Expand Up @@ -94,9 +95,10 @@ def afd_and_rd_sums_along_streamlines(sft, fodf, fodf_basis,
weight_map = np.zeros(shape=fodf_data.shape[:-1])

p_matrix = np.eye(fodf_data.shape[3]) * legendre0_at_n
all_crossed_indices = grid_intersections(sft.streamlines)
for crossed_indices in all_crossed_indices:
segments = crossed_indices[1:] - crossed_indices[:-1]
all_split_streamlines =\
subdivide_streamlines_at_voxel_faces(sft.streamlines)
for split_streamlines in all_split_streamlines:
segments = split_streamlines[1:] - split_streamlines[:-1]
seg_lengths = np.linalg.norm(segments, axis=1)

# Remove points where the segment is zero.
Expand All @@ -112,7 +114,7 @@ def afd_and_rd_sums_along_streamlines(sft, fodf, fodf_basis,
closest_vertex_indices = sorted_angles[:, 0]

# Those starting points are used for the segment vox_idx computations
strl_start = crossed_indices[non_zero_lengths]
strl_start = split_streamlines[non_zero_lengths]
vox_indices = (strl_start + (0.5 * segments)).astype(int)

normalization_weights = np.ones_like(seg_lengths)
Expand Down
12 changes: 7 additions & 5 deletions scilpy/tractanalysis/bingham_metric_along_streamlines.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import numpy as np
from scilpy.reconst.bingham import bingham_to_peak_direction
from scilpy.tractanalysis.grid_intersections import grid_intersections
from scilpy.tractanalysis.voxel_boundary_intersection import\
subdivide_streamlines_at_voxel_faces


def bingham_metric_map_along_streamlines(sft, bingham_coeffs,
Expand Down Expand Up @@ -73,9 +74,10 @@ def bingham_metric_sum_along_streamlines(sft, bingham_coeffs, metric,
weight_map = np.zeros(metric.shape[:-1])
min_cos_theta = np.cos(np.radians(max_theta))

all_crossed_indices = grid_intersections(sft.streamlines)
for crossed_indices in all_crossed_indices:
segments = crossed_indices[1:] - crossed_indices[:-1]
all_split_streamlines =\
subdivide_streamlines_at_voxel_faces(sft.streamlines)
for split_streamlines in all_split_streamlines:
segments = split_streamlines[1:] - split_streamlines[:-1]
seg_lengths = np.linalg.norm(segments, axis=1)

# Remove points where the segment is zero.
Expand All @@ -85,7 +87,7 @@ def bingham_metric_sum_along_streamlines(sft, bingham_coeffs, metric,
seg_lengths = seg_lengths[non_zero_lengths]

# Those starting points are used for the segment vox_idx computations
seg_start = crossed_indices[non_zero_lengths]
seg_start = split_streamlines[non_zero_lengths]
vox_indices = (seg_start + (0.5 * segments)).astype(int)

normalization_weights = np.ones_like(seg_lengths)
Expand Down
12 changes: 7 additions & 5 deletions scilpy/tractanalysis/fixel_density.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import numpy as np

from dipy.io.streamline import load_tractogram
from scilpy.tractanalysis.grid_intersections import grid_intersections
from scilpy.tractanalysis.voxel_boundary_intersection import\
subdivide_streamlines_at_voxel_faces


def _fixel_density_parallel(args):
Expand All @@ -21,9 +22,10 @@ def _fixel_density_single_bundle(bundle, peaks, max_theta, dps_key):

min_cos_theta = np.cos(np.radians(max_theta))

all_crossed_indices = grid_intersections(sft.streamlines)
for i, crossed_indices in enumerate(all_crossed_indices):
segments = crossed_indices[1:] - crossed_indices[:-1]
all_split_streamlines =\
subdivide_streamlines_at_voxel_faces(sft.streamlines)
for i, split_streamlines in enumerate(all_split_streamlines):
segments = split_streamlines[1:] - split_streamlines[:-1]
seg_lengths = np.linalg.norm(segments, axis=1)

# Remove points where the segment is zero.
Expand All @@ -33,7 +35,7 @@ def _fixel_density_single_bundle(bundle, peaks, max_theta, dps_key):
seg_lengths = seg_lengths[non_zero_lengths]

# Those starting points are used for the segment vox_idx computations
seg_start = crossed_indices[non_zero_lengths]
seg_start = split_streamlines[non_zero_lengths]
vox_indices = (seg_start + (0.5 * segments)).astype(int)

normalized_seg = np.reshape(segments / seg_lengths[..., None], (-1, 3))
Expand Down
12 changes: 7 additions & 5 deletions scilpy/tractanalysis/mrds_along_streamlines.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import numpy as np

from scilpy.tractanalysis.grid_intersections import grid_intersections
from scilpy.tractanalysis.voxel_boundary_intersection import\
subdivide_streamlines_at_voxel_faces


def mrds_metrics_along_streamlines(sft, mrds_pdds,
Expand Down Expand Up @@ -79,9 +80,10 @@ def mrds_metric_sums_along_streamlines(sft, mrds_pdds, metrics,
weight_map = np.zeros(metrics[0].shape[:-1])
min_cos_theta = np.cos(np.radians(max_theta))

all_crossed_indices = grid_intersections(sft.streamlines)
for crossed_indices in all_crossed_indices:
segments = crossed_indices[1:] - crossed_indices[:-1]
all_split_streamlines =\
subdivide_streamlines_at_voxel_faces(sft.streamlines)
for split_streamlines in all_split_streamlines:
segments = split_streamlines[1:] - split_streamlines[:-1]
seg_lengths = np.linalg.norm(segments, axis=1)

# Remove points where the segment is zero.
Expand All @@ -91,7 +93,7 @@ def mrds_metric_sums_along_streamlines(sft, mrds_pdds, metrics,
seg_lengths = seg_lengths[non_zero_lengths]

# Those starting points are used for the segment vox_idx computations
seg_start = crossed_indices[non_zero_lengths]
seg_start = split_streamlines[non_zero_lengths]
vox_indices = (seg_start + (0.5 * segments)).astype(int)

normalization_weights = np.ones_like(seg_lengths)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,23 @@ cdef struct Pointers:
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
def grid_intersections(streamlines):
def subdivide_streamlines_at_voxel_faces(streamlines):
"""
Cut streamlines segments into smaller segments such that a segment covering
more than one voxel is split into smaller segments that either end or start
at voxel boundaries.
Parameters
----------
streamlines: list of ndarray
Streamlines coordinates in voxel space, corner origin.
Returns
-------
split_coordinates: list of ndarray
Updated streamline coordinates with added coordinate points
at voxel boundaries.
"""
cdef:
cnp.npy_intp nb_streamlines = len(streamlines._lengths)
cnp.npy_intp at_point = 0
Expand Down
13 changes: 8 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ def get_extensions():
['scilpy/tractograms/uncompress.pyx'])
quick_tools = Extension('scilpy.tractanalysis.quick_tools',
['scilpy/tractanalysis/quick_tools.pyx'])
grid_intersections = Extension('scilpy.tractanalysis.grid_intersections',
['scilpy/tractanalysis/grid_intersections.pyx'])
streamlines_metrics = Extension('scilpy.tractanalysis.streamlines_metrics',
['scilpy/tractanalysis/streamlines_metrics.pyx'])
return [uncompress, quick_tools, grid_intersections, streamlines_metrics]
voxel_boundary_intersection =\
Extension('scilpy.tractanalysis.voxel_boundary_intersection',
['scilpy/tractanalysis/voxel_boundary_intersection.pyx'])
streamlines_metrics =\
Extension('scilpy.tractanalysis.streamlines_metrics',
['scilpy/tractanalysis/streamlines_metrics.pyx'])
return [uncompress, quick_tools,
voxel_boundary_intersection, streamlines_metrics]


class CustomBuildExtCommand(build_ext):
Expand Down

0 comments on commit a5b490c

Please sign in to comment.