-
Notifications
You must be signed in to change notification settings - Fork 5
/
KUL_FWT_make_TCKs.sh
executable file
·1829 lines (1091 loc) · 57.4 KB
/
KUL_FWT_make_TCKs.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
set -x
# the point of this one is to make my life easier!
# when it comes to VOI gen
cwd="$(pwd)"
# conda init bash
# conda deactivate
# pip install 'numpy==1.18'
# pip install 'nibabel==3.0.2'
# function Usage
function Usage {
cat <<USAGE
`basename $0` part of the KUL_FWT package of fully automated workflows for fiber tracking
Usage:
`basename $0` -p pat001 -s 01 -F /path_to/FS_dir/aparc+aseg.mgz -M /path_to/MSBP_dir/sub-pat001_label-L2018_desc-scale3_atlas.nii.gz -d /path_to/dMRI_dir -c /path_to/KUL_FWT_tracks_list.txt -o /fullpath/output -T 2 -f 2
Examples:
`basename $0` -p pat001 -s 01 -F /path_to/FS_dir/aparc+aseg.mgz -M /path_to/MSBP_dir/sub-pat001_label-L2018_desc-scale3_atlas.nii.gz -d /path_to/dMRI_dir -c /path_to/KUL_FWT_tracks_list.txt -o /fullpath/output -n 6 -T 1 -f 1 -S -Q
Purpose:
This workflow creates all bundles specified in the input config file using the inclusion and exclusion VOIs created by KUL_FWT_make_VOIs.sh for single subject data
Required arguments:
-p: BIDS participant name (anonymised name of the subject without the "sub-" prefix)
-s: BIDS participant session (session no. without the "ses-" prefix)
-T: Tracking and segmentation approach (1 = Bundle-specific tckgen, 2 = Whole brain tckgen & bundle segmentation)
-M: Full path and file name of scale 3 MSBP parcellation
-F: Full path and file name of aparc+aseg.mgz from FreeSurfer
-c: Path to config file with list of tracks to segment from the whole brain tractogram
-d: Path to directory with diffusion data (specific to subject and run)
-o: Full path to output dir (if not set reverts to default output ./sub-*_ses-*_KUL_FWT_output)
Optional arguments:
-a: Specify algorithm for tckgen fiber tractography (tckgen -algorithm options are: iFOD2, iFOD1, SD_STREAM, Tensor_Det, Tensor_Prob)
-f: Specify filtering approach (0 = No filtering, 1 = conservative, 2 = liberal)
-Q: If set quantitative and qualitative analyses will be done
-S: If set screenshots will taken of each bundle
-n: Number of cpu for parallelisation (default is 6)
-h: Prints help menu
USAGE
exit 1
}
# add this later
# -b: if using BIDS and all data is in BIDS/derivatives
# CHECK COMMAND LINE OPTIONS -------------
#
# Set defaults
# Set required options
p_flag=0
s_flag=0
T_flag=0
F_flag=0
M_flag=0
c_flag=0
d_flag=0
o_flag=0
a_flag=0
Q_flag=0
S_flag=0
filt_fl1=0
if [ "$#" -lt 1 ]; then
Usage >&2
exit 1
else
while getopts "p:s:T:M:F:c:d:o:a:n:f:hQS" OPT; do
case $OPT in
p) #participant
p_flag=1
subj=$OPTARG
;;
s) #session
s_flag=1
ses=$OPTARG
;;
M) #MSBP scale parcellation
M_flag=1
MS_sc3_in=$OPTARG
;;
T) #Tractography approach
T_flag=1
T_app=$OPTARG
;;
F) #FS aparc+aseg.mgz
F_flag=1
FS_apas_in=$OPTARG
;;
c) #config file
c_flag=1
conf_f=$OPTARG
;;
d) #diffusion dir
d_flag=1
d_dir=$OPTARG
;;
a) #algorithm flag
a_flag=1
algo_f=$OPTARG
;;
f) #filtering flag
filt_fl1=1
filt_fl2=$OPTARG
;;
Q) #Quant and Qual flag
Q_flag=1
;;
S) #Screenshots flag
S_flag=1
;;
o) #output
o_flag=1
out_dir=$OPTARG
;;
n) #parallel
n_flag=1
ncpu=$OPTARG
;;
h) #help
Usage >&2
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
echo
Usage >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
echo
Usage >&2
exit 1
;;
esac
done
fi
# deal with ncpu and itk ncpu
# MRTRIX verbose or not?
# if [ $silent -eq 1 ] ; then
# export MRTRIX_QUIET=1
# fi
# REST OF SETTINGS ---
# timestamp
start=$(date +%s)
d=$(date "+%Y-%m-%d_%H-%M-%S")
# check for required inputs
# config file
srch_conf_str=($(basename ${conf_f})) ; conf_dir=($(dirname ${conf_f}))
srch_conf_c=($(find ${conf_dir} -type f | grep ${srch_conf_str}))
# diffusion data dir
srch_ddir_str=($(basename ${d_dir})) ; diff_dir=($(dirname ${d_dir}))
srch_ddir_c=($(find ${diff_dir} -type d | grep ${srch_ddir_str}))
# FS dirs
srch_FS_str=($(basename ${FS_apas_in})) ; FS_dir=($(dirname ${FS_apas_in}))
srch_FS_c=($(find ${FS_dir} -type f | grep ${srch_FS_str}))
# MSBP dirs
srch_MS_str=($(basename ${MS_sc3_in})) ; MS_dir=($(dirname ${MS_sc3_in}))
srch_MS_c=($(find ${MS_dir} -type f | grep ${srch_MS_str}))
if [[ ${p_flag} -eq 0 ]] || [[ ${F_flag} -eq 0 ]] || [[ ${T_flag} -eq 0 ]] || [[ ${M_flag} -eq 0 ]] || [[ ${c_flag} -eq 0 ]] || [[ ${d_flag} -eq 0 ]]; then
echo
echo "Inputs to -p -F -M -d and -c must be set." >&2
echo
exit 2
else
if [[ -z "${srch_FS_c}" ]]; then
echo
echo " Incorrect path to the FS aparc+aseg, please check the path and name "
echo
exit 2
fi
if [[ -z "${srch_MS_c}" ]]; then
echo
echo " Incorrect path MSBP parcellation, please check the path and name "
echo
exit 2
fi
if [[ -z "${srch_ddir_c}" ]]; then
echo
echo " Incorrect path to the diffusion data dir, please check the dir path and name "
echo
exit 2
fi
if [[ -z "${srch_conf_c}" ]]; then
echo
echo " Incorrect config file, please check the path and name "
echo
exit 2
fi
if [[ ! ${d_dir} == *"${subj}"* ]] || [[ ! ${FS_dir} == *"${subj}"* ]] || [[ ! ${MS_dir} == *"${subj}"* ]]; then
echo
echo " Subject string does not match input files, please double check your inputs "
echo
exit 2
else
if [[ ! -z ${ses} ]]; then
if [[ ! ${d_dir} == *"ses-${ses}"* ]] || [[ ! ${FS_dir} == *"ses-${ses}"* ]] || [[ ! ${MS_dir} == *"ses-${ses}"* ]]; then
echo
echo " Session string does not match input files, please double check your inputs "
echo
exit 2
fi
fi
fi
echo "Inputs are -p ${subj} -s ${ses} -c ${conf_f} -d ${d_dir} -F ${FS_dir} -M ${MS_dir} -T ${T_app}"
fi
# set this manually for debugging
# this is now searching for the genVOIs script
function_path=($(which KUL_FWT_make_TCKs.sh | rev | cut -d"/" -f2- | rev))
mrtrix_path=($(which mrmath | rev | cut -d"/" -f3- | rev))
if [[ -z ${function_path} ]]; then
echo "update function path to reflect function name line 215"
# exit 2
else
echo " KUL_FWT lives in ${function_path} "
fi
# deal with scan sessions
if [[ -z ${s_flag} ]]; then
# no session flag defined
ses_str="";
ses_str_dir="";
elif [[ ${s_flag} -eq 1 ]]; then
# this is fine
ses_str="_ses-${ses}";
ses_str_dir="/ses-${ses}/";
fi
# REST OF SETTINGS ---
# Some parallelisation
if [[ "$n_flag" -eq 0 ]]; then
ncpu=6
echo " -n flag not set, using default 6 threads. "
else
echo " -n flag set, using " ${ncpu} " threads."
fi
FSLPARALLEL=$ncpu; export FSLPARALLEL
OMP_NUM_THREADS=$ncpu; export OMP_NUM_THREADS
# Priors dir and check
## change the temps dir name later
pr_d="${function_path}/KUL_FWT_templates"
if [[ ! -d ${pr_d} ]]; then
echo "KUL_FWT priors directory not found where expected, exiting"
exit 2
fi
# handle the dirs
cd ${cwd}
# handle output and processing dirs
if [[ "$o_flag" -eq 1 ]]; then
output_d="${out_dir}"
else
output_d="${cwd}/sub-${subj}${ses_str}_KUL_FWT_output"
fi
# output sub-dirs
TCKs_prepd="${output_d}/sub-${subj}${ses_str}_TCKs_prep"
TCKs_outd="${output_d}/sub-${subj}${ses_str}_TCKs_output"
# make your dirs
mkdir -p ${output_d} >/dev/null 2>&1
mkdir -p ${TCKs_outd} >/dev/null 2>&1
mkdir -p ${TCKs_prepd} >/dev/null 2>&1
# make your log file
prep_log2="${output_d}/KUL_FWT_TCKs_log_${subj}_${d}.txt";
if [[ ! -f ${prep_log2} ]] ; then
touch ${prep_log2}
else
echo "${prep_log2} already created"
fi
# deal with tracking algorithm
if [[ "$T_app" -eq 0 ]]; then
echo " -T flag is not set, exitting"
echo " Please specify the fiber tracking approach to use"
exit 2
else
if [[ "$T_app" -eq 1 ]]; then
Tracto=1
elif [[ "$T_app" -eq 2 ]]; then
Tracto=2
else
echo " Incorrect choice of fiber tracking approach, please select 1 or 2"
exit 2
fi
fi
# # filtering scheme selection
if [[ "${filt_fl1}" -eq 0 ]]; then
filt_fl2=2
echo " No filtering scheme selected, we will do liberal filtering by default " | tee -a ${prep_log2}
Alfa=0.48
else
if [[ ${filt_fl2} =~ ^[+-]?[0-9]+$ ]]; then
if [[ ${filt_fl2} -eq 0 ]]; then
echo " No filtering selected " | tee -a ${prep_log2}
elif [[ ${filt_fl2} -eq 1 ]]; then
echo " Conservative filtering selected " | tee -a ${prep_log2}
Alfa=0.48
elif [[ ${filt_fl2} -eq 2 ]]; then
echo " Liberal filtering selected " | tee -a ${prep_log2}
Alfa=0.38
else
echo "incorrect input to -f flag (filtering option selection), exiting "
exit 2
fi
else
echo "incorrect input to -f flag (filtering option selection), exiting "
exit 2
fi
fi
# Report on quanti, quali and screenshot workflows
if [[ "${Q_flag}" -eq 0 ]]; then
echo "Quantitative and qualitative analysis switched on" | tee -a ${prep_log2}
fi
if [[ "${S_flag}" -eq 0 ]]; then
echo "Screenshots switched on" | tee -a ${prep_log2}
fi
# set mrtrix tmp dir to prep_d
rm -rf ${TCKs_prepd}/tmp_dir_*
tmpo_d="${TCKs_prepd}/tmp_dir_${d}"
mkdir -p "${tmpo_d}" >/dev/null 2>&1
export MRTRIX_TMPFILE_DIR="${tmpo_d}"
# report pid
processId=$(ps -ef | grep 'ABCD' | grep -v 'grep' | awk '{ printf $2 }')
echo $processId
echo "KUL_FWT_make_TCKs.sh @ ${d} with parent pid $$ and process pid $BASHPID " | tee -a ${prep_log2}
echo "Inputs are -p sub-${subj} -s ses-${ses} -c ${conf_f} -d ${d_dir} -F ${FS_dir} -M ${MS_dir} " | tee -a ${prep_log2}
# read the config file
# if a hash is found this cell is populated with ##
declare -a tck_lst1
declare -a tck_list
declare -a nosts_list
# tck_lst1=($(cat ${conf_f}))
# tck_lst1=($(cat ${conf_f}))
IFS=$'\n' read -d '' -r -a tck_lst1 < ${conf_f}
for i in ${!tck_lst1[@]}; do
if [[ ${tck_lst1[$i]} == *"#"* ]]; then
tck_list[$i]="none"
else
# tck_list[$i]=${tck_lst1[$i]}
tck_list[$i]=$(echo ${tck_lst1[$i]} | cut -d ',' -f1)
# test to make sure tck_list[$i] contains a string
if [[ ${tck_list[$i]} =~ ^[+-]?[0-9]+$ ]]; then
echo " there is a problem with config file, first column does not contain a string"
exit 2
fi
nosts_list[$i]=$(echo ${tck_lst1[$i]} | cut -d ',' -f2)
# test to make sure nosts_list[$i] contains a number
if [[ ! ${nosts_list[$i]} =~ ^[+-]?[0-9]+$ ]]; then
echo " there is a problem with config file, second column does not contain numbers"
exit 2
fi
fi
done
# unset tcks_lst1
# now echo this
echo "You have asked to segment the following bundles from whole brain TCK ${tck_list[@]}" | tee -a ${prep_log2}
# Exec_all function
# need to recreate this function to include proc. control
function task_exec {
echo "-------------------------------------------------------------" | tee -a ${prep_log2}
echo ${task_in} | tee -a ${prep_log2}
echo " Started @ $(date "+%Y-%m-%d_%H-%M-%S")" | tee -a ${prep_log2}
eval ${task_in} 2>&1 | tee -a ${prep_log2} &
# echo " pid = $! basicPID = $BASHPID " | tee -a ${prep_log2}
echo " pid = $! " | tee -a ${prep_log2}
wait ${pid}
sleep 5
echo "exit status $?" | tee -a ${prep_log2}
# if [ $? -eq 0 ]; then
# echo Success >> ${prep_log2}
# else
# echo Fail >> ${prep_log2}
# exit 1
# fi
echo " Finished @ $(date "+%Y-%m-%d_%H-%M-%S")" | tee -a ${prep_log2}
echo "-------------------------------------------------------------" | tee -a ${prep_log2}
echo "" | tee -a ${prep_log2}
unset task_in
}
# function for tckedit or tckgen for each bundle
function make_bundle {
echo "---------------------" | tee -a ${prep_log2}
echo ${tcks_2_make} | tee -a ${prep_log2}
# echo " Started @ $(date "+%Y-%m-%d_%H-%M-%S")" | tee -a ${prep_log2}
# we need 2 - 3 arrays per tck (includes labels, and excludes, and hemi excludes)
# https://stackoverflow.com/questions/16553089/dynamic-variable-names-in-bash
# found out how to do dynamic variable naming
# to use dynamic variable definitions in bash
# eval v_array=( \${${tck}_array[@]})
# updated this line to clear local vars at the start
unset TCK_I TCK_X auto_X tracking_mask
TCK_2_make=${TCK_to_make}
# Handle dirs for prep and output of TCK
# TCK_prep="${TCKs_prepd}/${TCK_2_make}_prep"
TCK_out="${TCKs_outd}/${TCK_2_make}_output"
# mkdir -p "${TCK_prep}" >/dev/null 2>&1
mkdir -p "${TCK_out}" >/dev/null 2>&1
# define includes and excludes
TCK_I_b=($(find ${ROIs_d}/${TCK_2_make}_VOIs/${TCK_2_make}_incs*/${TCK_2_make}_incs*_bin.nii.gz));
TCK_I_m=($(find ${ROIs_d}/${TCK_2_make}_VOIs/${TCK_2_make}_incs*/${TCK_2_make}_incs*_map.nii.gz));
TCK_X_b=($(find ${ROIs_d}/${TCK_2_make}_VOIs/${TCK_2_make}_excs/${TCK_2_make}_excs_bin.nii.gz));
# these guys say map but they r actually binary
TCK_Is_MNI=($(find ${ROIs_d}/${TCK_2_make}_VOIs_inMNI/${TCK_2_make}_incs*_map_inMNI.nii.gz));
# define auto_excludes based on laterality
if [[ ${TCK_2_make} == *"DRT_LT"* ]]; then
echo " Right DRT " | tee -a ${prep_log2}
auto_X=" -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_wv.nii.gz -exclude ${ROIs_d}/custom_VOIs/cerebellum_LT_X.nii.gz "
auto_X_f=" --drawn_roi ${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_wv.nii.gz any exclude --drawn_roi ${ROIs_d}/custom_VOIs/cerebellum_LT_X.nii.gz any exclude"
elif [[ ${TCK_2_make} == *"DRT_RT"* ]]; then
echo " Left DRT " | tee -a ${prep_log2}
auto_X=" -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_wv.nii.gz -exclude ${ROIs_d}/custom_VOIs/cerebellum_RT_X.nii.gz "
auto_X_f=" --drawn_roi ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_wv.nii.gz any exclude --drawn_roi ${ROIs_d}/custom_VOIs/cerebellum_RT_X.nii.gz any exclude"
elif [[ ${TCK_2_make} == *"Fx_LT"* ]]; then
echo " Left Fornix " | tee -a ${prep_log2}
# removed -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_nv.nii.gz
# removed --drawn_roi ${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_nv.nii.gz any exclude
auto_X=" -exclude ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz "
auto_X_f=" --drawn_roi ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz any exclude"
elif [[ ${TCK_2_make} == *"Fx_RT"* ]]; then
echo " Right Fornix " | tee -a ${prep_log2}
# removed -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_nv.nii.gz
# removed --drawn_roi ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_nv.nii.gz any exclude
auto_X=" -exclude ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz "
auto_X_f=" --drawn_roi ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz any exclude"
else
if [[ ${TCK_2_make} == *"_Comm" ]] ; then
echo " ${TCK_2_make} a commissural or midline bundle " | tee -a ${prep_log2}
auto_X=" -exclude ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz "
auto_X_f=" --drawn_roi ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz any exclude"
elif [[ ${TCK_2_make} == *"CP_LT"* ]] ; then
echo " Cerebellar bundle " | tee -a ${prep_log2}
auto_X=" -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_wv.nii.gz -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_wv.nii.gz \
-exclude ${ROIs_d}/custom_VOIs/cerebellum_RT_X.nii.gz"
auto_X_f=" --drawn_roi ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_wv.nii.gz any exclude --drawn_roi \
${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_wv.nii.gz any exclude --drawn_roi ${ROIs_d}/custom_VOIs/cerebellum_RT_X.nii.gz any exclude"
elif [[ ${TCK_2_make} == *"CP_RT"* ]] ; then
echo " Cerebellar bundle " | tee -a ${prep_log2}
auto_X=" -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_wv.nii.gz -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_wv.nii.gz \
-exclude ${ROIs_d}/custom_VOIs/cerebellum_LT_X.nii.gz"
auto_X_f=" --drawn_roi ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_wv.nii.gz any exclude --drawn_roi \
${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_wv.nii.gz any exclude --drawn_roi ${ROIs_d}/custom_VOIs/cerebellum_LT_X.nii.gz any exclude"
elif [[ ${TCK_2_make} == *"LT"* ]] ; then
echo " Left sided bundle " | tee -a ${prep_log2}
auto_X=" -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_wv.nii.gz -exclude ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz "
auto_X_f=" --drawn_roi ${ROIs_d}/custom_VOIs/cerebrum_hemi_RT_X_wv.nii.gz any exclude --drawn_roi ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz any exclude"
elif [[ ${TCK_2_make} == *"RT"* ]]; then
echo " Right sided bundle " | tee -a ${prep_log2}
auto_X=" -exclude ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_wv.nii.gz -exclude ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz "
auto_X_f=" --drawn_roi ${ROIs_d}/custom_VOIs/cerebrum_hemi_LT_X_wv.nii.gz any exclude --drawn_roi ${ROIs_d}/custom_VOIs/cerebellum_Bil_X.nii.gz any exclude "
else
echo " ${TCK_2_make} will not need hemispheric excludes " | tee -a ${prep_log2}
auto_X=""
auto_X_f=""
fi
fi
# define include and exclude strings for tckgen &/or tckedit
includes_str=$(printf " -include %s" "${TCK_I_b[@]}")
seeds_str=$(printf " -seed_image %s" "${TCK_I_b[@]}")
excludes_str=$(printf " -exclude %s" "${TCK_X_b[@]}")
# run tckgen or tckedit depending on the ${T_app}
# Must differentiate between BST and WBTS
tracking_mask="${T1_brain_mask_inFA}"
# if it's an OR or AF use the minCSF
if [[ ${TCK_2_make} == *"OR_"* ]] || [[ ${TCK_2_make} == *"AF_"* ]] || [[ ${TCK_2_make} == *"CP_"* ]] || [[ ${TCK_2_make} == *"DRT_"* ]] ; then
tracking_mask="${T1_BM_inFA_minCSF}"
else
tracking_mask="${T1_brain_mask_inFA}"
fi
if [[ ${TCK_2_make} == *"CP_"* ]] || [[ ${TCK_2_make} == *"DRT_"* ]]; then
excludes_str+=$(printf " -exclude %s" "${MSBP_csf_mask}")
fi
if [[ ${T_app} == 1 ]]; then
T="BT"
tck_init="${TCK_out}/${TCK_2_make}_initial_${T}_${algo_f}.tck"
tck_init_inT="${TCK_out}/${TCK_2_make}_initial_${T}_${algo_f}_inMNI.tck"
# cmd_str="tckgen -force -nthreads ${ncpu} -algorithm ${algo_f} -angle 45 \
# -select ${ns} -maxlength 280 -minlength 20 \
# -mask ${tracking_mask} ${seeds_str} ${includes_str} ${excludes_str} ${auto_X} ${tracking_source} ${tck_init}"
cmd_str="tckgen -force -nthreads ${ncpu} -algorithm ${algo_f} \
-select ${ns} -maxlength 280 -minlength 20 \
-mask ${tracking_mask} ${seeds_str} ${includes_str} ${excludes_str} ${auto_X} ${tracking_source} ${tck_init}"
elif [[ ${T_app} == 2 ]]; then
T="WB"
tck_init="${TCK_out}/${TCK_2_make}_initial_${T}_${algo_f}.tck"
tck_init_inT="${TCK_out}/${TCK_2_make}_initial_${T}_${algo_f}_inMNI.tck"
cmd_str="tckedit -force -nthreads ${ncpu} -maxlength 280 -minlength 10 -tck_weights_in ${TCKs_outd}/sub-${subj}${ses_str}_sift2_ws.txt \
-mask ${tracking_mask} -minweight 0.08 ${includes_str} ${excludes_str} ${auto_X} ${WB_tck} ${tck_init}"
fi
# define scilpy filtering strings
# we only use the start and end includes, i.e. the first and last for the includes array
# need to add condition for bilateral - commissural bundles
if [[ ${TCK_2_make} == *"_Comm" ]]; then
# should ensure that all bundles of this kind start with the midline VOI as inc1, and incs2 & 3 as the cortical VOIs
drawn_incs_str=$(printf " --drawn_roi %s any include " "${TCK_I_b[0]}")
drawn_incs_str+=$(printf " --drawn_roi %s either_end include " "${TCK_I_b[${#TCK_I_b[@]}-1]}")
drawn_incs_str+=$(printf " --drawn_roi %s either_end include " "${TCK_I_b[${#TCK_I_b[@]}-2]}")
else
if [[ ${TCK_2_make} == *"CST"* ]] || [[ ${TCK_2_make} == *"PyT"* ]] || [[ ${TCK_2_make} == *"ML_"* ]]; then
drawn_incs_str=$(printf " --drawn_roi %s any include " "${ROIs_d}/custom_VOIs/BStemr_custom.nii.gz")
else
drawn_incs_str=$(printf " --drawn_roi %s any include " "${TCK_I_b[0]}")
fi
# it's better to define this differently depending on the number of VOIs
# i.e. if only 2 incs then easy, end to inc, if more then end for inc1 then any for middle and end for inc(N)
# trying with either_end for both includes if only 2 are selected
# this deals with the rest of the filtering string
unset vsz
vsz="${#TCK_I_b[@]}"
if [[ ${vsz} -eq 2 ]]; then
if [[ ${TCK_2_make} == *"OR_LT"* ]] || [[ ${TCK_2_make} == *"OR_RT"* ]]; then
drawn_incs_str+=$(printf " --drawn_roi %s any include " "${TCK_I_b[1]}")
else
drawn_incs_str+=$(printf " --drawn_roi %s any include " "${TCK_I_b[1]}")
fi
elif [[ ${vsz} -gt 2 ]]; then
for vi in ${TCK_I_b[@]:1:$((vsz-2))}; do
drawn_incs_str+=$(printf " --drawn_roi %s any include " "${TCK_I_b[$vi]}")
done
drawn_incs_str+=$(printf " --drawn_roi %s any include " "${TCK_I_b[${vsz}-1]}")
fi
fi
# excludes will always be the same
drawn_excs_str=$(printf " --drawn_roi %s any exclude " "${TCK_X_b[@]}")
# processing control for initial tracking/segmentation
if [[ ! -f "${tck_init}" ]]; then
task_in="${cmd_str}"
task_exec
task_in="tcktransform -force ${tck_init} ${TCKs_w2temp} ${tck_init_inT}"
task_exec
count=($(tckstats -force -nthreads ${ncpu} -output count ${tck_init} -quiet ));
else
count=($(tckstats -force -nthreads ${ncpu} -output count ${tck_init} -quiet ));
if [[ ! -f ${tck_init_inT} ]]; then
task_in="tcktransform -force ${tck_init} ${TCKs_w2temp} ${tck_init_inT}"
task_exec
fi
if [[ ${count} -gt 10 ]]; then
echo " ${TCK_2_make}_initial.tck already done, skipping " | tee -a ${prep_log2}
# count=($(tckstats -force -nthreads ${ncpu} -output count ${tck_init} -quiet ));
# report initial yield
echo " ${TCK_2_make} has ${count} streamlines initially " | tee -a ${prep_log2}
else
task_in="${cmd_str}"
task_exec
count=($(tckstats -force -nthreads ${ncpu} -output count ${tck_init} -quiet ));
fi
fi
# need to create combined incs_bin maps for QQ
# loop from 2nd element in incs_bin array
if [[ ! -f "${TCK_out}/${TCK_2_make}_incs_map_agg_inMNI.nii.gz" ]]; then
((funn=${#TCK_I_b[@]}-1));
mrcal_strs=$(printf " %s " "${TCK_I_b[0]}")
for fun in $(seq 1 ${funn}); do
((funme=${fun}+1))
task_in="mrcalc -force -quiet -nthreads ${ncpu} ${TCK_I_b[$fun]} 0 -gt ${funme} -mult \
${tmpo_d}/${TCK_2_make}_incs_map_init${funme}.nii.gz"
task_exec
mrcal_strs+=$(printf " %s -add " "${tmpo_d}/${TCK_2_make}_incs_map_init${funme}.nii.gz")
done
# WIP we mult the result agg map by 10 to ease separating heads from toes
task_in="mrcalc -force -quiet -nthreads ${ncpu} ${mrcal_strs} 0 -gt ${tmpo_d}/${TCK_2_make}_incs_map_agg_bin.nii.gz"
task_exec
task_in="mrcalc -force -quiet -nthreads ${ncpu} ${mrcal_strs} ${tmpo_d}/${TCK_2_make}_incs_map_agg_bin.nii.gz -mult 10 -mult ${TCK_out}/${TCK_2_make}_incs_map_agg.nii.gz"
task_exec
task_in="antsApplyTransforms -d 3 -i ${TCK_out}/${TCK_2_make}_incs_map_agg.nii.gz -o ${TCK_out}/${TCK_2_make}_incs_map_agg_inMNI.nii.gz -r ${UKBB_temp} \
-t ${prep_d}/FS_2_UKBB_${subj}${ses_str}_1Warp.nii.gz \
-t [${prep_d}/FS_2_UKBB_${subj}${ses_str}_0GenericAffine.mat,0] \
-t ${prep_d}/fa_2_UKBB_vFS_${subj}${ses_str}_1Warp.nii.gz \
-t [${prep_d}/fa_2_UKBB_vFS_${subj}${ses_str}_0GenericAffine.mat,0]"
task_exec
fi
# including scil_filter_tracts by default as soon as the initial bundle is generated
# with the exception of the ORs where FBC is used
# if the bundle has more than 0 streamlines, look whether filt1.tck has already been generated
# then look at whether it is an OR or not
tck_filt1="${TCK_out}/${TCK_2_make}_filt1_${T}_${algo_f}.tck"
tck_filt2="${TCK_out}/${TCK_2_make}_filt2_${T}_${algo_f}.tck"
tck_filt3="${TCK_out}/${TCK_2_make}_filt3_${T}_${algo_f}.tck"
tck_filt5="${TCK_out}/${TCK_2_make}_fin_${T}_${algo_f}.tck"
tck_filt5_centroid1="${TCK_out}/QQ/tmp/${TCK_2_make}_fin_${T}_${algo_f}_inMNI_centroid1.tck"
tck_filt1_inT="${TCK_out}/${TCK_2_make}_filt1_${T}_${algo_f}_inMNI.tck"
tck_filt3_inT="${TCK_out}/${TCK_2_make}_filt3_${T}_${algo_f}_inMNI.tck"
tck_filt5_inT="${TCK_out}/${TCK_2_make}_fin_${T}_${algo_f}_inMNI.tck"
tck_rs1_inT="${TCK_out}/QQ/tmp/${TCK_2_make}_fin_${T}_${algo_f}_rs1c_inMNI.tck"
# MNI_segs1="${TCK_out}/QQ/tmp/${TCK_2_make}_fin_${T}_${algo_f}_rs51_segments1_inMNI.nii.gz"
tck_cent1_HT_map="${TCK_out}/QQ/tmp/${TCK_2_make}_fin_${T}_${algo_f}_mapped_inMNI.nii.gz"
MNI_segs="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_rs1c_segments_inMNI.nii.gz"
# MNI_segsd="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_rs1c_segments_inMNI_debug.nii.gz"
# MNI_segs3="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_rs50_segments3_inMNI.nii.gz"
MNI_agg="${TCK_out}/QQ/${TCK_2_make}_incs_map_agg_inMNI.nii.gz"
TCKs_curve="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_curve_inMNI.nii.gz"
TCKs_tdi="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_tdi_inMNI.nii.gz"
TCKs_length="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_length_inMNI.nii.gz"
# tck_4QQ_inT="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_4QQ.tck"
# tck_segs1="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_rs51_segments1_inMNI.nii.gz"
lego_1="${TCK_out}/QQ/tmp/${TCK_2_make}_fin_${T}_${algo_f}_lego1.nii.gz"
lego_2="${TCK_out}/QQ/tmp/${TCK_2_make}_fin_${T}_${algo_f}_lego2.nii.gz"
tckp1_4QQ_inT="${TCK_out}/QQ/tmp/${TCK_2_make}_fin_${T}_${algo_f}_4QQ_seg1.tck"
tck_reor="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_inMNI_rTCK.tck"
tckc_reor="${TCK_out}/QQ/${TCK_2_make}_fin_${T}_${algo_f}_inMNI_centroid_rTCK.tck"
if [[ ${count} -gt 10 ]] && [[ ! ${filt_fl2} == 0 ]]; then
if [[ ! -f "${TCK_out}/${TCK_2_make}_fin_map_${T}_${algo_f}_inMNI.nii.gz" ]]; then
if [[ ! ${TCK_2_make} == "O"* ]]; then
echo " We use scilpy filtering and outlier rejection for ${TCK_2_make} " | tee -a ${prep_log2}
if [[ ! -f ${tck_filt1} ]]; then
task_in="scil_filter_tractogram.py -f --reference ${subj_FA} ${drawn_incs_str} ${drawn_excs_str} ${auto_X_f} ${tck_init} ${tck_filt1}"
task_exec
sleep 2
count2=($(tckstats -force -nthreads ${ncpu} -output count ${tck_filt1} -quiet ));
else
echo " ${TCK_2_make} initial filtering already done, skipping " | tee -a ${prep_log2}
fi
if [[ -f ${tck_filt1} ]] && [[ ! -f ${tck_filt5} ]] && [[ ${count2} -gt 10 ]]; then
task_in="tckmap -precise -force -nthreads ${ncpu} -template ${subj_FA} ${tck_filt1} \
${TCK_out}/${TCK_2_make}_filt1_map_${T}_${algo_f}.nii.gz && mrcalc -datatype uint16 -force -nthreads ${ncpu} \
${TCK_out}/${TCK_2_make}_filt1_map_${T}_${algo_f}.nii.gz 0 -gt ${TCK_out}/${TCK_2_make}_filt1_map_mask_${T}_${algo_f}.nii.gz"
task_exec &
task_in="scil_detect_streamlines_loops.py -f --reference ${subj_FA} ${tck_filt1} ${tck_filt2}"
task_exec
task_in="scil_outlier_rejection.py -f --alpha ${Alfa} --reference ${subj_FA} ${tck_filt2} ${tck_filt3}"
task_exec
task_in="scil_smooth_streamlines.py -f --gaussian 5 --reference ${subj_FA} ${tck_filt3} ${tck_filt5}"
task_exec
task_in="tcktransform -force ${tck_filt3} ${TCKs_w2temp} ${tck_filt3_inT}"
task_exec
else
echo " ${TCK_2_make} initial filtering failed, skipping " | tee -a ${prep_log2}
fi
elif [[ ${TCK_2_make} == "O"* ]]; then
echo " We use FBC filtering for the optic radiations " | tee -a ${prep_log2}
if [[ ! -f ${tck_filt1} ]]; then