From 6b682e427cc3f0619676cd001a141ab2f2a2676e Mon Sep 17 00:00:00 2001 From: Gabriel Girard Date: Thu, 12 Dec 2024 14:37:11 -0500 Subject: [PATCH 1/2] DOC - rename uncompress fct to streamlines_to_voxel_coordinates --- docs/source/fake_files/uncompress.py | 2 +- .../connectivity_segmentation.py | 7 +-- .../streamline_and_mask_operations.py | 34 +++++++------- .../test_streamline_and_mask_operations.py | 47 ++++++++++++------- scilpy/tractograms/uncompress.pyx | 8 ++-- ...ctogram_segment_connections_from_labels.py | 7 ++- 6 files changed, 62 insertions(+), 43 deletions(-) diff --git a/docs/source/fake_files/uncompress.py b/docs/source/fake_files/uncompress.py index 299629a31..d0f72ea87 100644 --- a/docs/source/fake_files/uncompress.py +++ b/docs/source/fake_files/uncompress.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -def uncompress(): +def streamlines_to_voxel_coordinates(): pass diff --git a/scilpy/tractanalysis/connectivity_segmentation.py b/scilpy/tractanalysis/connectivity_segmentation.py index 3c236b958..b4d35d588 100644 --- a/scilpy/tractanalysis/connectivity_segmentation.py +++ b/scilpy/tractanalysis/connectivity_segmentation.py @@ -96,7 +96,8 @@ def compute_connectivity(indices, atlas_data, real_labels, segmenting_func): ---------- indices: ArraySequence The list of 3D indices [i, j, k] of all voxels traversed by all - streamlines. This is the output of our uncompress function. + streamlines. This is the output of the + streamlines_to_voxel_coordinates function. atlas_data: np.ndarray The loaded image containing the labels. real_labels: np.ndarray @@ -155,9 +156,9 @@ def construct_hdf5_from_connectivity( sft: StatefulTractogram The tractogram. indices: ArraySequence - Results from uncompress. + Results from streamlines_to_voxel_coordinates. points_to_idx: ArraySequence - Results from uncompress. + Results from streamlines_to_voxel_coordinates. real_labels: np.ndarray The labels. con_info: dict diff --git a/scilpy/tractograms/streamline_and_mask_operations.py b/scilpy/tractograms/streamline_and_mask_operations.py index c151774ef..7b8a74f0d 100644 --- a/scilpy/tractograms/streamline_and_mask_operations.py +++ b/scilpy/tractograms/streamline_and_mask_operations.py @@ -9,7 +9,7 @@ from scipy.ndimage import map_coordinates -from scilpy.tractograms.uncompress import uncompress +from scilpy.tractograms.uncompress import streamlines_to_voxel_coordinates from scilpy.tractograms.streamline_operations import \ resample_streamlines_step_size @@ -87,8 +87,8 @@ def get_head_tail_density_maps(sft, point_to_select=1, to_millimeters=False): streamlines = sft.streamlines dimensions = sft.dimensions - # Uncompress the streamlines to get the indices of the voxels intersected - list_indices, points_to_indices = uncompress( + # Get the indices of the voxels intersected + list_indices, points_to_indices = streamlines_to_voxel_coordinates( streamlines, return_mapping=True) # Initialize the endpoints maps @@ -292,13 +292,16 @@ def cut_streamlines_with_mask( sft.to_vox() sft.to_corner() - # Uncompress the streamlines to get the indices of the voxels + # Get the indices of the voxels # intersected by the streamlines and the mapping from points to indices - indices, points_to_idx = uncompress(sft.streamlines, - return_mapping=True) + indices, points_to_idx = streamlines_to_voxel_coordinates( + sft.streamlines, + return_mapping=True + ) if len(sft.streamlines[0]) != len(points_to_idx[0]): - raise ValueError("Error in the uncompress function. Try running the " + raise ValueError("Error in the streamlines_to_voxel_coordinates " + "function. Try running the " "scil_tractogram_remove_invalid.py script with the \n" "--remove_single_point and " "--remove_overlapping_points options.") @@ -383,10 +386,14 @@ def cut_streamlines_between_labels( mask = label_data_2 != unique_vals[1] label_data_2[mask] = 0 - (indices, points_to_idx) = uncompress(sft.streamlines, return_mapping=True) + (indices, points_to_idx) = streamlines_to_voxel_coordinates( + sft.streamlines, + return_mapping=True + ) if len(sft.streamlines[0]) != len(points_to_idx[0]): - raise ValueError("Error in the uncompress function. Try running the " + raise ValueError("Error in the streamlines_to_voxel_coordinates " + "function. Try running the " "scil_tractogram_remove_invalid.py script with the \n" "--remove_single_point and " "--remove_overlapping_points options.") @@ -624,15 +631,8 @@ def compute_streamline_segment(orig_strl, inter_vox, in_vox_idx, out_vox_idx, nb_points = nb_points_orig_strl + nb_add_points orig_segment_len = len(orig_strl[in_strl_point:out_strl_point + 1]) - # TODO: Fix the bug in `uncompress` and remove this - # There is a bug with `uncompress` where the number of `points_to_indices` - # is not the same as the number of points in the streamline. This is - # a temporary fix. - segment_len = min( - nb_points, - orig_segment_len + nb_add_points) # Initialize the new streamline segment - segment = np.zeros((segment_len, 3)) + segment = np.zeros((nb_points, 3)) # offset for indexing in case there are new points offset = 0 diff --git a/scilpy/tractograms/tests/test_streamline_and_mask_operations.py b/scilpy/tractograms/tests/test_streamline_and_mask_operations.py index 772c41a6a..d6c8a0dcc 100644 --- a/scilpy/tractograms/tests/test_streamline_and_mask_operations.py +++ b/scilpy/tractograms/tests/test_streamline_and_mask_operations.py @@ -21,7 +21,7 @@ get_head_tail_density_maps, CuttingStyle) from scilpy.image.labels import get_labels_from_mask -from scilpy.tractograms.uncompress import uncompress +from scilpy.tractograms.uncompress import streamlines_to_voxel_coordinates fetch_data(get_testing_files_dict(), keys=['tractograms.zip']) @@ -147,12 +147,15 @@ def test_trim_streamline_in_mask(): sft.to_vox() sft.to_corner() - idices, points_to_idx = uncompress(sft.streamlines, return_mapping=True) - strl_indices = idices[0] - points_to_idices = points_to_idx[0] + indices, points_to_idx = streamlines_to_voxel_coordinates( + sft.streamlines, + return_mapping=True + ) + strl_indices = indices[0] + points_to_indices = points_to_idx[0] cut = _trim_streamline_in_mask( - strl_indices, sft.streamlines[0], points_to_idices, center_roi) + strl_indices, sft.streamlines[0], points_to_indices, center_roi) in_result = os.path.join(SCILPY_HOME, 'tractograms', 'streamline_and_mask_operations', @@ -200,12 +203,15 @@ def test_trim_streamline_in_mask_keep_longest(): sft.to_vox() sft.to_corner() - idices, points_to_idx = uncompress(sft.streamlines, return_mapping=True) - strl_indices = idices[0] - points_to_idices = points_to_idx[0] + indices, points_to_idx = streamlines_to_voxel_coordinates( + sft.streamlines, + return_mapping=True + ) + strl_indices = indices[0] + points_to_indices = points_to_idx[0] cut = _trim_streamline_in_mask_keep_longest( - strl_indices, sft.streamlines[0], points_to_idices, center_roi) + strl_indices, sft.streamlines[0], points_to_indices, center_roi) in_result = os.path.join(SCILPY_HOME, 'tractograms', 'streamline_and_mask_operations', @@ -250,12 +256,15 @@ def test_trim_streamline_endpoints_in_mask(): sft.to_vox() sft.to_corner() - idices, points_to_idx = uncompress(sft.streamlines, return_mapping=True) - strl_indices = idices[0] - points_to_idices = points_to_idx[0] + indices, points_to_idx = streamlines_to_voxel_coordinates( + sft.streamlines, + return_mapping=True + ) + strl_indices = indices[0] + points_to_indices = points_to_idx[0] cut = _trim_streamline_endpoints_in_mask( - strl_indices, sft.streamlines[0], points_to_idices, + strl_indices, sft.streamlines[0], points_to_indices, head_tail_offset_rois) in_result = os.path.join(SCILPY_HOME, 'tractograms', @@ -334,10 +343,14 @@ def test_compute_streamline_segment(): # Split head and tail from mask roi_data_1, roi_data_2 = split_mask_blobs_kmeans( - head_tail_offset_rois, nb_clusters=2) - - (indices, points_to_idx) = uncompress(one_sft.streamlines, - return_mapping=True) + head_tail_offset_rois, + nb_clusters=2 + ) + + (indices, points_to_idx) = streamlines_to_voxel_coordinates( + one_sft.streamlines, + return_mapping=True + ) strl_indices = indices[0] # Find the first and last "voxels" of the streamline that are in the diff --git a/scilpy/tractograms/uncompress.pyx b/scilpy/tractograms/uncompress.pyx index 01b1cd912..d27f7260d 100644 --- a/scilpy/tractograms/uncompress.pyx +++ b/scilpy/tractograms/uncompress.pyx @@ -32,7 +32,7 @@ cdef struct Pointers: @cython.boundscheck(False) @cython.cdivision(True) -def uncompress(streamlines, return_mapping=False): +def streamlines_to_voxel_coordinates(streamlines, return_mapping=False): """ Get the indices of the voxels traversed by each streamline; then returns an ArraySequence of indices, i.e. [i, j, k] coordinates. @@ -102,7 +102,9 @@ def uncompress(streamlines, return_mapping=False): pointers.points_to_index_out = &points_to_index_view_out[0] while 1: - at_point = _uncompress(&pointers, at_point, max_points - 1) + at_point = _streamlines_to_voxel_coordinates(&pointers, + at_point, + max_points - 1) if pointers.lengths_in == pointers.lengths_in_end: # Job finished, we can return the streamlines break @@ -147,7 +149,7 @@ cdef inline void c_get_closest_edge(double *p, @cython.boundscheck(False) @cython.cdivision(True) -cdef cnp.npy_intp _uncompress( +cdef cnp.npy_intp _streamlines_to_voxel_coordinates( Pointers* pointers, cnp.npy_intp at_point, cnp.npy_intp max_points) nogil: diff --git a/scripts/scil_tractogram_segment_connections_from_labels.py b/scripts/scil_tractogram_segment_connections_from_labels.py index 407d69323..ba4b528ef 100755 --- a/scripts/scil_tractogram_segment_connections_from_labels.py +++ b/scripts/scil_tractogram_segment_connections_from_labels.py @@ -84,7 +84,7 @@ compute_connectivity, construct_hdf5_from_connectivity, extract_longest_segments_from_profile) -from scilpy.tractograms.uncompress import uncompress +from scilpy.tractograms.uncompress import streamlines_to_voxel_coordinates def _get_output_paths(args): @@ -277,7 +277,10 @@ def main(): # Get the indices of the voxels traversed by each streamline logging.info('*** Computing voxels traversed by each streamline ***') time1 = time.time() - indices, points_to_idx = uncompress(sft.streamlines, return_mapping=True) + indices, points_to_idx = streamlines_to_voxel_coordinates( + sft.streamlines, + return_mapping=True + ) time2 = time.time() logging.info(' Streamlines intersection took {} sec.'.format( round(time2 - time1, 2))) From c9d62fb61bc5ab0fbaf3312a81b17881524549ad Mon Sep 17 00:00:00 2001 From: Gabriel Girard Date: Thu, 9 Jan 2025 15:37:57 -0500 Subject: [PATCH 2/2] PEP8 --- scilpy/tractograms/tests/test_streamline_and_mask_operations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scilpy/tractograms/tests/test_streamline_and_mask_operations.py b/scilpy/tractograms/tests/test_streamline_and_mask_operations.py index d6c8a0dcc..c2d5b7caf 100644 --- a/scilpy/tractograms/tests/test_streamline_and_mask_operations.py +++ b/scilpy/tractograms/tests/test_streamline_and_mask_operations.py @@ -343,7 +343,7 @@ def test_compute_streamline_segment(): # Split head and tail from mask roi_data_1, roi_data_2 = split_mask_blobs_kmeans( - head_tail_offset_rois, + head_tail_offset_rois, nb_clusters=2 )