-
Notifications
You must be signed in to change notification settings - Fork 437
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
RecoBundles and SLR workflows #1556
Changes from 100 commits
e783ccb
357fc7d
02d3f54
06f6801
21d17c4
92a4570
3c929a0
e0f641a
6deb2ca
8c390dd
785cb93
cccc0a9
3a7ef2d
8981e12
6fdbff9
1d41f92
5cf7b73
36cb544
5e50e50
05d9bf4
a146223
92726d2
df4e0fc
0344c6f
600306a
d2d60f8
611d5ae
201f3e3
4d33ad7
c5a2c05
ce7b47e
08d2375
d825dcc
0084e95
e30a907
0e2cde0
1a7803c
3fba917
efce412
314910f
d4444f2
a2613e6
fd58d5c
8599ea0
9709895
7f92246
dbc54c8
ca8e5f1
ff9bfa8
7a5ab24
4515735
5956129
4a43af0
e67d897
6b41858
9535aa3
b9ff2ed
de13111
5500804
d2cfe28
859076f
3bbe451
09e2700
6ad254c
0f0dcd9
af05527
d9efb2a
464a6d9
c5167e1
d825597
92753a1
7e85aee
5faabdf
5adb9d1
083f417
f116b55
ef077f2
4298311
1886828
1be009d
8e9412a
163888e
d51bd90
0379b5a
52ade24
8b54e12
a4e4f2a
1a00caf
193d31c
c5eb946
87a969e
6ab92f3
1a72259
bc53a42
28464a0
76825d7
25afa7d
66dc1ad
068e71b
d650429
ced0dcb
f9c3850
a933f33
b741e58
a89a93d
3c8f76b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!python | ||
|
||
from __future__ import division, print_function | ||
|
||
from dipy.workflows.flow_runner import run_flow | ||
from dipy.workflows.segment import LabelsBundlesFlow | ||
|
||
if __name__ == "__main__": | ||
run_flow(LabelsBundlesFlow()) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!python | ||
|
||
from __future__ import division, print_function | ||
|
||
from dipy.workflows.flow_runner import run_flow | ||
from dipy.workflows.segment import RecoBundlesFlow | ||
|
||
if __name__ == "__main__": | ||
run_flow(RecoBundlesFlow()) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!python | ||
|
||
from __future__ import division, print_function | ||
|
||
from dipy.workflows.flow_runner import run_flow | ||
from dipy.workflows.align import SlrWithQbxFlow | ||
|
||
if __name__ == "__main__": | ||
run_flow(SlrWithQbxFlow()) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,13 +10,15 @@ | |
center_streamlines, | ||
set_number_of_points, | ||
select_random_set_of_streamlines, | ||
length) | ||
from dipy.segment.clustering import QuickBundles | ||
length, | ||
Streamlines) | ||
from dipy.segment.clustering import QuickBundles, qbx_and_merge | ||
from dipy.core.geometry import (compose_transformations, | ||
compose_matrix, | ||
decompose_matrix) | ||
from dipy.utils.six import string_types | ||
from time import time | ||
from dipy.tracking.streamline import Streamlines | ||
|
||
MAX_DIST = 1e10 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why |
||
LOG_MAX_DIST = np.log(MAX_DIST) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
@@ -693,8 +695,15 @@ def bundle_min_distance_asymmetric_fast(t, static, moving, block_size): | |
|
||
|
||
def remove_clusters_by_size(clusters, min_size=0): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add documentation for this function? |
||
|
||
by_size = lambda c: len(c) >= min_size | ||
return filter(by_size, clusters) | ||
ob = filter(by_size, clusters) | ||
|
||
centroids = Streamlines() | ||
for cluster in ob: | ||
centroids.append(cluster.centroid) | ||
|
||
return centroids | ||
|
||
|
||
def progressive_slr(static, moving, metric, x0, bounds, | ||
|
@@ -828,18 +837,17 @@ def progressive_slr(static, moving, metric, x0, bounds, | |
|
||
return slm | ||
|
||
|
||
def slr_with_qb(static, moving, | ||
x0='affine', | ||
rm_small_clusters=50, | ||
maxiter=100, | ||
select_random=None, | ||
verbose=False, | ||
greater_than=50, | ||
less_than=250, | ||
qb_thr=15, | ||
nb_pts=20, | ||
progressive=True, num_threads=None): | ||
def slr_with_qbx(static, moving, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pep8: expected 2 blanks lines |
||
x0='affine', | ||
rm_small_clusters=50, | ||
maxiter=100, | ||
select_random=None, | ||
verbose=False, | ||
greater_than=50, | ||
less_than=250, | ||
qbx_thr=[40, 30, 20, 15], | ||
nb_pts=20, | ||
progressive=True, rng=None, num_threads=None): | ||
""" Utility function for registering large tractograms. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add |
||
|
||
For efficiency we apply the registration on cluster centroids and remove | ||
|
@@ -865,6 +873,9 @@ def slr_with_qb(static, moving, | |
options : None or dict, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you remove |
||
Extra options to be used with the selected method. | ||
|
||
rng : RandomState | ||
If None creates RandomState in function. | ||
|
||
num_threads : int | ||
Number of threads. If None (default) then all available threads | ||
will be used. Only metrics using OpenMP will use this variable. | ||
|
@@ -886,6 +897,9 @@ def slr_with_qb(static, moving, | |
bundles using local and global streamline-based registration and | ||
clustering, Neuroimage, 2017. | ||
""" | ||
if rng is None: | ||
rng = np.random.RandomState() | ||
|
||
if verbose: | ||
print('Static streamlines size {}'.format(len(static))) | ||
print('Moving streamlines size {}'.format(len(moving))) | ||
|
@@ -898,8 +912,8 @@ def check_range(streamline, gt=greater_than, lt=less_than): | |
return False | ||
|
||
# TODO change this to the new Streamlines API | ||
streamlines1 = [s for s in static if check_range(s)] | ||
streamlines2 = [s for s in moving if check_range(s)] | ||
streamlines1 = Streamlines(static[np.array([check_range(s) for s in static])]) | ||
streamlines2 = Streamlines(moving[np.array([check_range(s) for s in moving])]) | ||
|
||
if verbose: | ||
|
||
|
@@ -910,29 +924,39 @@ def check_range(streamline, gt=greater_than, lt=less_than): | |
|
||
if select_random is not None: | ||
rstreamlines1 = select_random_set_of_streamlines(streamlines1, | ||
select_random) | ||
select_random, | ||
rng=rng) | ||
else: | ||
rstreamlines1 = streamlines1 | ||
|
||
rstreamlines1 = set_number_of_points(rstreamlines1, nb_pts) | ||
qb1 = QuickBundles(threshold=qb_thr) | ||
rstreamlines1 = [s.astype('f4') for s in rstreamlines1] | ||
cluster_map1 = qb1.cluster(rstreamlines1) | ||
|
||
# qb1 = QuickBundles(threshold=qb_thr) | ||
rstreamlines1._data.astype('f4') | ||
'''#rstreamlines1 = [s.astype('f4') for s in rstreamlines1] | ||
# cluster_map1 = qb1.cluster(rstreamlines1)''' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you remove this 2comment lines? |
||
|
||
cluster_map1 = qbx_and_merge(rstreamlines1, thresholds=qbx_thr, rng=rng) | ||
clusters1 = remove_clusters_by_size(cluster_map1, rm_small_clusters) | ||
qb_centroids1 = [cluster.centroid for cluster in clusters1] | ||
|
||
qb_centroids1 = clusters1 | ||
|
||
if select_random is not None: | ||
rstreamlines2 = select_random_set_of_streamlines(streamlines2, | ||
select_random) | ||
select_random, | ||
rng=rng) | ||
else: | ||
rstreamlines2 = streamlines2 | ||
|
||
rstreamlines2 = set_number_of_points(rstreamlines2, nb_pts) | ||
qb2 = QuickBundles(threshold=qb_thr) | ||
rstreamlines2 = [s.astype('f4') for s in rstreamlines2] | ||
cluster_map2 = qb2.cluster(rstreamlines2) | ||
rstreamlines2._data.astype('f4') | ||
'''# qb2 = QuickBundles(threshold=qb_thr) | ||
#rstreamlines2 = [s.astype('f4') for s in rstreamlines2] | ||
# cluster_map2 = qb2.cluster(rstreamlines2)''' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you remove this 3 comments lines |
||
cluster_map2 = qbx_and_merge(rstreamlines2, thresholds=qbx_thr, rng=rng) | ||
|
||
clusters2 = remove_clusters_by_size(cluster_map2, rm_small_clusters) | ||
qb_centroids2 = [cluster.centroid for cluster in clusters2] | ||
qb_centroids2 = clusters2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why you do not do directly
|
||
|
||
if verbose: | ||
t = time() | ||
|
@@ -967,7 +991,7 @@ def check_range(streamline, gt=greater_than, lt=less_than): | |
# Garyfallidis et al. Recognition of white matter | ||
# bundles using local and global streamline-based registration and | ||
# clustering, Neuroimage, 2017. | ||
whole_brain_slr = slr_with_qb | ||
whole_brain_slr = slr_with_qbx | ||
|
||
|
||
def _threshold(x, th): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
from __future__ import division, print_function, absolute_import | ||
|
||
import os | ||
import sys | ||
import contextlib | ||
|
@@ -32,6 +31,7 @@ | |
UW_RW_URL = \ | ||
"https://digital.lib.washington.edu/researchworks/bitstream/handle/" | ||
|
||
|
||
class FetcherError(Exception): | ||
pass | ||
|
||
|
@@ -430,6 +430,28 @@ def fetcher(): | |
" More details about the data are available in their paper: " + | ||
" https://www.nature.com/articles/sdata201672")) | ||
|
||
fetch_bundle_atlas_hcp842 = _make_fetcher( | ||
"fetch_bundle_atlas_hcp842", | ||
pjoin(dipy_home, 'bundle_atlas_hcp842'), | ||
'https://ndownloader.figshare.com/files/', | ||
['11921522'], | ||
['Atlas_in_MNI_Space_16_bundles.zip'], | ||
['b071f3e851f21ba1749c02fc6beb3118'], | ||
doc="Download atlas tractogram from the hcp842 dataset with its bundles", | ||
data_size="200MB", | ||
unzip=True) | ||
|
||
fetch_target_tractogram_hcp = _make_fetcher( | ||
"fetch_target_tractogram_hcp", | ||
pjoin(dipy_home, 'target_tractogram_hcp'), | ||
'https://ndownloader.figshare.com/files/', | ||
['12871127'], | ||
['hcp_tractogram.zip'], | ||
['fa25ef19c9d3748929b6423397963b6a'], | ||
doc="Download tractogram of one of the hcp dataset subjects", | ||
data_size="541MB", | ||
unzip=True) | ||
|
||
|
||
def read_scil_b0(): | ||
""" Load GE 3T b0 image form the scil b0 dataset. | ||
|
@@ -1031,4 +1053,61 @@ def read_cfin_t1(): | |
""" | ||
files, folder = fetch_cfin_multib() | ||
img = nib.load(pjoin(folder, 'T1.nii')) | ||
return img, gtab | ||
return img # , gtab | ||
|
||
|
||
def read_bundle_atlas_hcp842(): | ||
""" | ||
Returns | ||
------- | ||
file1 : string | ||
file2 : string | ||
""" | ||
file1 = pjoin(dipy_home, | ||
'bundle_atlas_hcp842', | ||
'Atlas_in_MNI_Space_16_bundles', | ||
'whole_brain', | ||
'whole_brain_MNI.trk') | ||
|
||
file2 = pjoin(dipy_home, | ||
'bundle_atlas_hcp842', | ||
'Atlas_in_MNI_Space_16_bundles', | ||
'bundles', | ||
'*.trk') | ||
|
||
return file1, file2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I expect the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi Serge, Thanks for the review. We decided to return just file location from read function because otherwise we would have to load all data files and return them, whereas user might just want to load few files. Like for the file2 it returns location to 16 bundles, and user might just want to load 2 or 3 of them, not all 16. |
||
|
||
|
||
def read_two_hcp842_bundle(): | ||
""" | ||
Returns | ||
------- | ||
file1 : string | ||
file2 : string | ||
""" | ||
file1 = pjoin(dipy_home, | ||
'bundle_atlas_hcp842', | ||
'Atlas_in_MNI_Space_16_bundles', | ||
'bundles', | ||
'AF_L.trk') | ||
|
||
file2 = pjoin(dipy_home, | ||
'bundle_atlas_hcp842', | ||
'Atlas_in_MNI_Space_16_bundles', | ||
'bundles', | ||
'CST_L.trk') | ||
|
||
return file1, file2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment as above |
||
|
||
|
||
def read_target_tractogram_hcp(): | ||
""" | ||
Returns | ||
------- | ||
file1 : string | ||
""" | ||
file1 = pjoin(dipy_home, 'target_tractogram_hcp', | ||
'hcp_tractogram', | ||
'streamlines.trk') | ||
|
||
return file1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment as above |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QuickBundles
is unused, can you remove it from this import?