Skip to content

Commit a379cc4

Browse files
authored
Merge pull request #456 from dPys/development
Development
2 parents 4951e5d + 8297b7a commit a379cc4

File tree

11 files changed

+266
-147
lines changed

11 files changed

+266
-147
lines changed

.duecredit.p

-92 Bytes
Binary file not shown.

Dockerfile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ RUN apt-get update -qq \
4848
libglu1-mesa-dev \
4949
libglib2.0-0 \
5050
libglw1-mesa \
51+
libxkbcommon-x11-0 \
5152
liblapack-dev \
5253
libopenblas-base \
5354
sqlite3 \
@@ -84,7 +85,10 @@ RUN apt-get update -qq \
8485
&& cp fsl/bin/* $FSLDIR/bin/ \
8586
&& rm -r fsl* \
8687
&& chmod 777 -R $FSLDIR/bin \
87-
&& chmod 777 -R /usr/lib/fsl/5.0
88+
&& chmod 777 -R /usr/lib/fsl/5.0 \
89+
&& echo "tmpfs /tmp tmpfs rw,nodev,nosuid,size=10G 0 0" >> /etc/fstab
90+
# && wget --retry-connrefused --waitretry=5 --read-timeout=60 --timeout=60 -t 0 -q -O examples.tar.gz "https://osf.io/ye4vf/download" && tar -xvzf examples.tar.gz -C /tmp \
91+
# && rm -rf examples.tar.gz
8892

8993
ENV FSLDIR=/usr/share/fsl/5.0 \
9094
FSLOUTPUTTYPE=NIFTI_GZ \
@@ -127,6 +131,7 @@ RUN echo "FSLDIR=/usr/share/fsl/5.0" >> /home/neuro/.bashrc && \
127131
&& pip install certifi -U --ignore-installed \
128132
&& pip install python-dateutil==2.8.0 \
129133
# && pip install skggm \
134+
&& pip install --upgrade --force-reinstall numpy \
130135
# Create nipype config for resource monitoring
131136
&& mkdir -p ~/.nipype \
132137
&& echo "[monitoring]" > ~/.nipype/nipype.cfg \
@@ -188,6 +193,7 @@ ENV PATH="/opt/conda/bin":$PATH
188193
ENV OPENBLAS_NUM_THREADS=4 \
189194
GOTO_NUM_THREADS=4 \
190195
OMP_NUM_THREADS=4
196+
ENV QT_QPA_PLATFORM=offscreen
191197

192198
# and add it as an entrypoint
193199
#ENTRYPOINT ["pynets"]

pynets/cli/pynets_collect.py

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ def load_pd_dfs(file_):
113113
except:
114114
print(f"Cannot load {file_}")
115115
df = pd.DataFrame()
116-
return df
117116
if "Unnamed: 0" in df.columns:
118117
df.drop(df.filter(regex="Unnamed: 0"), axis=1, inplace=True)
119118
id = op.basename(file_).split("_topology")[0].split('auc_')[1]
@@ -175,14 +174,13 @@ def load_pd_dfs(file_):
175174
os.remove(f"{file_.split('.csv')[0]}{'_clean.csv'}")
176175
df.to_csv(f"{file_.split('.csv')[0]}{'_clean.csv'}", index=False)
177176
del id
178-
177+
gc.collect()
179178
else:
180179
print(f"{Fore.RED}Cleaned {file_} missing...{Style.RESET_ALL}")
181180
df = pd.DataFrame()
182181
else:
183182
print(f"{Fore.RED}{file_} missing...{Style.RESET_ALL}")
184183
df = pd.DataFrame()
185-
gc.collect()
186184

187185
return df
188186

@@ -531,6 +529,7 @@ def load_pd_dfs_auc(atlas_name, prefix, auc_file, modality, drop_cols):
531529
from colorama import Fore, Style
532530
import pandas as pd
533531
import re
532+
import numpy as np
534533
import os
535534

536535
pd.set_option("display.float_format", lambda x: f"{x:.8f}")
@@ -545,8 +544,7 @@ def load_pd_dfs_auc(atlas_name, prefix, auc_file, modality, drop_cols):
545544
auc_file, chunksize=100000, compression="gzip",
546545
encoding="utf-8", engine='python').read()
547546
except:
548-
df_pref = pd.DataFrame()
549-
return df_pref
547+
df = pd.DataFrame()
550548

551549
#print(f"{'Atlas: '}{atlas_name}")
552550
prefix = f"{atlas_name}{'_'}{prefix}{'_'}"
@@ -813,6 +811,7 @@ def collect_all(working_path, modality, drop_cols):
813811
def build_collect_workflow(args, retval):
814812
import os
815813
import glob
814+
import psutil
816815
import warnings
817816
warnings.filterwarnings("ignore")
818817
import ast
@@ -862,20 +861,6 @@ def build_collect_workflow(args, retval):
862861

863862
wf = collect_all(working_path, modality, drop_cols)
864863

865-
hardcoded_params = load_runconfig()
866-
runtime_dict = {}
867-
execution_dict = {}
868-
for i in range(len(hardcoded_params["resource_dict"])):
869-
runtime_dict[
870-
list(hardcoded_params["resource_dict"][i].keys())[0]
871-
] = ast.literal_eval(
872-
list(hardcoded_params["resource_dict"][i].values())[0][0]
873-
)
874-
for i in range(len(hardcoded_params["execution_dict"])):
875-
execution_dict[
876-
list(hardcoded_params["execution_dict"][i].keys())[0]
877-
] = list(hardcoded_params["execution_dict"][i].values())[0][0]
878-
879864
run_uuid = f"{strftime('%Y%m%d_%H%M%S')}_{uuid.uuid4()}"
880865
os.makedirs(f"{work_dir}/pynets_out_collection{run_uuid}", exist_ok=True)
881866
wf.base_dir = f"{work_dir}/pynets_out_collection{run_uuid}"
@@ -912,9 +897,30 @@ def build_collect_workflow(args, retval):
912897
handler = logging.FileHandler(callback_log_path)
913898
logger.addHandler(handler)
914899

900+
execution_dict = {}
915901
execution_dict["crashdump_dir"] = str(wf.base_dir)
916902
execution_dict["plugin"] = str(plugin_type)
903+
execution_dict["poll_sleep_duration"] = 0.5
904+
execution_dict["crashfile_format"] = "txt"
905+
execution_dict["local_hash_check"] = False
906+
execution_dict["stop_on_first_crash"] = False
907+
execution_dict['hash_method'] = 'timestamp'
908+
execution_dict["keep_inputs"] = True
909+
execution_dict["use_relative_paths"] = False
910+
execution_dict["remove_unnecessary_outputs"] = False
911+
execution_dict["remove_node_directories"] = False
912+
execution_dict["raise_insufficient"] = False
913+
nthreads = psutil.cpu_count() * 2
914+
procmem = [int(nthreads),
915+
int(list(psutil.virtual_memory())[4] / 1000000000) - 2]
916+
plugin_args = {
917+
"n_procs": int(procmem[0]),
918+
"memory_gb": int(procmem[1]),
919+
"scheduler": "topological_sort",
920+
}
921+
execution_dict["plugin_args"] = plugin_args
917922
cfg = dict(execution=execution_dict)
923+
918924
for key in cfg.keys():
919925
for setting, value in cfg[key].items():
920926
wf.config[key][setting] = value
@@ -976,7 +982,8 @@ def main():
976982
args_dict_all['plug'] = 'MultiProc'
977983
args_dict_all['v'] = False
978984
#args_dict_all['pm'] = '48,67'
979-
args_dict_all['pm'] = '224,2000'
985+
args_dict_all['pm'] = '128,500'
986+
#args_dict_all['pm'] = '224,2000'
980987
#args_dict_all['basedir'] = '/working/tuning_set/outputs_clustering/pynets'
981988
#args_dict_all['basedir'] = '/working/tuning_set/outputs_shaeffer/pynets'
982989
#args_dict_all['basedir'] = '/working/tuning_set/outputs_language/pynets'

pynets/cli/pynets_run.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ def build_workflow(args, retval):
795795
import psutil
796796
nthreads = psutil.cpu_count()
797797
procmem = [int(nthreads),
798-
int(list(psutil.virtual_memory())[4]/1000000000) - 2]
798+
int(list(psutil.virtual_memory())[4]/1000000000) - 1]
799799
else:
800800
procmem = list(eval(str(resources)))
801801
procmem[1] = procmem[1] - 1

pynets/core/interfaces.py

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,7 @@ def _run_interface(self, runtime):
11541154
import gc
11551155
import time
11561156
import glob
1157+
import os
11571158
import os.path as op
11581159
from pynets.registration import register
11591160
from nipype.utils.filemanip import fname_presuffix, copyfile
@@ -1347,6 +1348,22 @@ def _run_interface(self, runtime):
13471348
self._results["t1w2dwi_xfm"] = reg.t1w2dwi_xfm
13481349
self._results["wm_gm_int_in_dwi"] = reg.wm_gm_int_in_dwi
13491350

1351+
reg_tmp = [
1352+
fa_tmp_path,
1353+
mask_tmp_path,
1354+
reg.warp_t1w2mni,
1355+
reg.t1w_head,
1356+
reg.wm_edge,
1357+
reg.vent_mask_dwi,
1358+
reg.vent_mask_t1w,
1359+
reg.corpuscallosum_mask_t1w,
1360+
reg.corpuscallosum_dwi
1361+
]
1362+
for j in reg_tmp:
1363+
if j is not None:
1364+
if os.path.isfile(j):
1365+
os.system(f"rm -f {j} &")
1366+
13501367
gc.collect()
13511368

13521369
return runtime
@@ -1745,6 +1762,8 @@ def _run_interface(self, runtime):
17451762
t1w2dwi_bbr_xfm_tmp_path,
17461763
t1w2dwi_xfm_tmp_path,
17471764
wm_gm_int_in_dwi_tmp_path,
1765+
aligned_atlas_skull,
1766+
t1w_brain_tmp_path
17481767
]
17491768
for j in reg_tmp:
17501769
if j is not None:
@@ -1922,6 +1941,9 @@ def _run_interface(self, runtime):
19221941
mni2t1w_warp_tmp_path,
19231942
t1wtissue2dwi_xfm_tmp_path,
19241943
mni2t1_xfm_tmp_path,
1944+
template_tmp_path,
1945+
roi_in_t1w,
1946+
roi_file_tmp_path
19251947
]
19261948
for j in reg_tmp:
19271949
if j is not None:
@@ -2238,6 +2260,8 @@ def _run_interface(self, runtime):
22382260
uatlas_tmp_path,
22392261
template_tmp_path,
22402262
t1w2mni_xfm_tmp_path,
2263+
t1w2mni_warp_tmp_path,
2264+
template_mask_tmp_path
22412265
]
22422266

22432267
for j in reg_tmp:
@@ -2612,6 +2636,7 @@ def _run_interface(self, runtime):
26122636
mni2t1w_warp_tmp_path,
26132637
mni2t1_xfm_tmp_path,
26142638
roi_file_tmp_path,
2639+
template_tmp_path
26152640
]
26162641
for j in reg_tmp:
26172642
if j is not None:
@@ -3036,35 +3061,37 @@ def _run_interface(self, runtime):
30363061
print(Style.RESET_ALL)
30373062

30383063
# Commence Ensemble Tractography
3039-
streamlines = track_ensemble(
3040-
self.inputs.target_samples,
3041-
labels_im_file_tmp_path_wm_gm_int,
3042-
labels_im_file_tmp_path,
3043-
recon_path,
3044-
get_sphere(sphere),
3045-
self.inputs.directget,
3046-
self.inputs.curv_thr_list,
3047-
self.inputs.step_list,
3048-
self.inputs.track_type,
3049-
self.inputs.maxcrossing,
3050-
int(roi_neighborhood_tol),
3051-
self.inputs.min_length,
3052-
waymask_tmp_path,
3053-
B0_mask_tmp_path,
3054-
t1w2dwi_tmp_path, gm_in_dwi_tmp_path,
3055-
vent_csf_in_dwi_tmp_path, wm_in_dwi_tmp_path,
3056-
self.inputs.tiss_class,
3057-
runtime.cwd
3058-
)
3059-
3060-
gc.collect()
3064+
try:
3065+
streamlines = track_ensemble(
3066+
self.inputs.target_samples,
3067+
labels_im_file_tmp_path_wm_gm_int,
3068+
labels_im_file_tmp_path,
3069+
recon_path,
3070+
get_sphere(sphere),
3071+
self.inputs.directget,
3072+
self.inputs.curv_thr_list,
3073+
self.inputs.step_list,
3074+
self.inputs.track_type,
3075+
self.inputs.maxcrossing,
3076+
int(roi_neighborhood_tol),
3077+
self.inputs.min_length,
3078+
waymask_tmp_path,
3079+
B0_mask_tmp_path,
3080+
t1w2dwi_tmp_path, gm_in_dwi_tmp_path,
3081+
vent_csf_in_dwi_tmp_path, wm_in_dwi_tmp_path,
3082+
self.inputs.tiss_class,
3083+
runtime.cwd
3084+
)
3085+
gc.collect()
3086+
except BaseException:
3087+
print(UserWarning("Tractography failed..."))
3088+
streamlines = None
30613089

30623090
if streamlines is not None:
30633091
# import multiprocessing
30643092
# from pynets.core.utils import kill_process_family
30653093
# return kill_process_family(int(multiprocessing.current_process().pid))
30663094

3067-
30683095
# Linear Fascicle Evaluation (LiFE)
30693096
if use_life is True:
30703097
print('Using LiFE to evaluate streamline plausibility...')
@@ -3143,7 +3170,10 @@ def _run_interface(self, runtime):
31433170
else:
31443171
self._results["streams"] = None
31453172
self._results["dm_path"] = None
3146-
tmp_files = [gtab_file_tmp_path, labels_im_file_tmp_path_wm_gm_int]
3173+
tmp_files = [gtab_file_tmp_path,
3174+
labels_im_file_tmp_path_wm_gm_int,
3175+
wm_in_dwi_tmp_path, gm_in_dwi_tmp_path,
3176+
vent_csf_in_dwi_tmp_path, t1w2dwi_tmp_path]
31473177

31483178
for j in tmp_files:
31493179
if j is not None:

pynets/core/nodemaker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,7 @@ def gen_network_parcels(uatlas, network, labels, dir_path):
12031203
)
12041204
out_path = f"{dir_path}" \
12051205
f"/{op.basename(uatlas).split(op.splitext(uatlas)[1])[0]}_" \
1206-
f"{network}{'_parcels.nii.gz'}"
1206+
f"{network}_parcels.nii.gz"
12071207
nib.save(nib.Nifti1Image(net_parcels_sum, affine=np.eye(4)), out_path)
12081208
del net_parcels_concatted, img_list
12091209
gc.collect()

pynets/dmri/estimation.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ def streams2graph(
532532
https://doi.org/10.1089/brain.2016.0481
533533
"""
534534
import gc
535+
import os
535536
import time
536537
from dipy.tracking.streamline import Streamlines, values_from_volume
537538
from dipy.tracking._utils import _mapping_to_voxel, _to_voxel_coordinates
@@ -552,7 +553,7 @@ def streams2graph(
552553
overlap_thr = hardcoded_params[
553554
"StructuralNetworkWeighting"]["overlap_thr"][0]
554555
roi_neighborhood_tol = \
555-
hardcoded_params['tracking']["roi_neighborhood_tol"][0]
556+
hardcoded_params['tracking']["roi_neighborhood_tol"][0]
556557

557558
start = time.time()
558559

@@ -589,7 +590,8 @@ def streams2graph(
589590
# from fury import actor, window
590591
# renderer = window.Renderer()
591592
# template_actor = actor.contour_from_roi(roi_img.get_fdata(),
592-
# color=(50, 50, 50), opacity=0.05)
593+
# color=(50, 50, 50),
594+
# opacity=0.05)
593595
# renderer.add(template_actor)
594596
# lines_actor = actor.streamtube(streamlines, window.colors.orange,
595597
# linewidth=0.3)
@@ -707,7 +709,7 @@ def streams2graph(
707709
# Adapted from the nnormalized fiber-density estimation routines of
708710
# Sebastian Tourbier.
709711
if fiber_density is True:
710-
print("Weighting edges by fiber density...")
712+
print("Redefining edges on the basis of fiber density...")
711713
# Summarize total fibers and total label volumes
712714
total_fibers = 0
713715
total_volume = 0
@@ -734,7 +736,7 @@ def streams2graph(
734736
ix += 1
735737

736738
if fa_wei is True:
737-
print("Weighting edges by FA...")
739+
print("Re-weighting edges by FA...")
738740
# Add FA attributes for each edge
739741
ix = 0
740742
for u, v, d in g.edges(data=True):

0 commit comments

Comments
 (0)