-
Notifications
You must be signed in to change notification settings - Fork 5
/
cat_batch_cat.sh
executable file
·634 lines (545 loc) · 19 KB
/
cat_batch_cat.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
#! /bin/bash
# Call CAT12 standard pipeline from shell
# ______________________________________________________________________
#
# Christian Gaser, Robert Dahnke
# Structural Brain Mapping Group (https://neuro-jena.github.io)
# Departments of Neurology and Psychiatry
# Jena University Hospital
# ______________________________________________________________________
# $Id$
########################################################
# global parameters
########################################################
matlab=matlab # you can use other matlab versions by changing the matlab parameter
cwd=$(dirname "$0")
cat12_dir=$cwd
spm12=$(dirname "$cwd")
spm12=$(dirname "$spm12")
LOGDIR=$PWD
CPUINFO=/proc/cpuinfo
ARCH=`uname`
time=`date "+%Y%b%d_%H%M"`
nicelevel=0
defaults_tmp=/tmp/defaults$$.m
no_mwp=0
no_surf=0
rp=0
TEST=0
fg=0
bids=0
bids_folder=
nojvm=""
NUMBER_OF_JOBS=-1
########################################################
# run main
########################################################
main ()
{
parse_args ${1+"$@"}
check_matlab
check_files
get_no_of_cpus
modifiy_defaults
run_cat12
exit 0
}
########################################################
# check arguments and files
########################################################
parse_args ()
{
local optname optarg
count=0
if [ $# -lt 1 ]; then
help
exit 1
fi
while [ $# -gt 0 ]; do
optname="`echo $1 | sed 's,=.*,,'`"
optarg="`echo $2`"
paras="$paras $optname $optarg"
case "$1" in
--matlab* | -m*)
exit_if_empty "$optname" "$optarg"
matlab=$optarg
shift
;;
--defaults* | -d*)
exit_if_empty "$optname" "$optarg"
defaults=$optarg
shift
;;
--nprocesses* | -np*)
exit_if_empty "$optname" "$optarg"
NUMBER_OF_JOBS="-$optarg"
shift
;;
--processes* | -p*)
exit_if_empty "$optname" "$optarg"
NUMBER_OF_JOBS=$optarg
shift
;;
--logdir* | -l*)
exit_if_empty "$optname" "$optarg"
LOGDIR=$optarg
if [ ! -d $LOGDIR ]; then
mkdir -p $LOGDIR
fi
shift
;;
--no-mwp* | -nm*)
exit_if_empty "$optname" "$optarg"
no_mwp=1
;;
--no-surf* | -ns*)
exit_if_empty "$optname" "$optarg"
no_surf=1
;;
--rp* | -r*)
exit_if_empty "$optname" "$optarg"
rp=1
;;
--nojvm | -nj)
exit_if_empty "$optname" "$optarg"
nojvm=" -nojvm "
;;
--no-overwrite* | -no*)
exit_if_empty "$optname" "$optarg"
no_overwrite=$optarg
shift
;;
--n* | -n* | --nice* | -nice*)
exit_if_empty "$optname" "$optarg"
nicelevel=$optarg
shift
;;
--add* | -a*)
exit_if_empty "$optname" "$optarg"
add_to_defaults="$optarg"
shift
;;
--fg* | -fg*)
exit_if_empty "$optname" "$optarg"
fg=1
;;
--files* | -f*)
exit_if_empty "$optname" "$optarg"
listfile=$optarg
shift
list=$(< $listfile);
for F in $list; do
ARRAY[$count]=$F
((count++))
done
;;
--bids_folder* | --bids-folder* | -bf*)
exit_if_empty "$optname" "$optarg"
bids_folder=$optarg
shift
;;
--b* | -b*)
exit_if_empty "$optname" "$optarg"
bids=1
;;
--s* | -s* | --shell* | -shell*)
exit_if_empty "$optname" "$optarg"
shellcommand=$optarg
shift
;;
--tpm* | -tpm*)
exit_if_empty "$optname" "$optarg"
tpm=$optarg
shift
;;
--test* | -t*)
TEST=1
;;
--c* | -c* | --command* | -command*)
exit_if_empty "$optname" "$optarg"
matlabcommand=$optarg
shift
;;
-h | --help | -v | --version | -V)
help
exit 1
;;
-*)
echo "`basename $0`: ERROR: Unrecognized option \"$1\"" >&2
;;
*)
ARRAY[$count]=$1
((count++))
;;
esac
shift
done
}
########################################################
# check arguments
########################################################
exit_if_empty ()
{
local desc val
desc="$1"
shift
val="$*"
if [ ! -n "$val" ]; then
echo 'ERROR: No argument given with \"$desc\" command line argument!' >&2
exit 1
fi
}
########################################################
# check files
########################################################
check_files ()
{
if [ "$no_surf" -eq 1 ] && [ "$no_mwp" -eq 1 ] && [ "$rp" -eq 0 ]; then
echo 'WARNING: You have deselected all outputs! Only the p0-image is saved.' >&2
fi
SIZE_OF_ARRAY="${#ARRAY[@]}"
if [ "$SIZE_OF_ARRAY" -eq 0 ]; then
echo 'ERROR: No files given!' >&2
help
exit 1
fi
i=0
while [ "$i" -lt "$SIZE_OF_ARRAY" ]; do
if [ ! -f "${ARRAY[$i]}" ]; then
if [ ! -L "${ARRAY[$i]}" ]; then
echo ERROR: File ${ARRAY[$i]} not found
help
exit 1
fi
fi
((i++))
done
}
########################################################
# get # of cpus
########################################################
# modified code from
# PPSS, the Parallel Processing Shell Script
#
# Copyright (c) 2009, Louwrentius
# All rights reserved.
get_no_of_cpus () {
if [ ! -n "$NUMBER_OF_JOBS" ] | [ $NUMBER_OF_JOBS -le -1 ]; then
if [ "$ARCH" == "Linux" ]; then
NUMBER_OF_PROC=`grep ^processor $CPUINFO | wc -l`
elif [ "$ARCH" == "Darwin" ]; then
NUMBER_OF_PROC=`sysctl -a hw | grep -w hw.logicalcpu | awk '{ print $2 }'`
elif [ "$ARCH" == "FreeBSD" ]; then
NUMBER_OF_PROC=`sysctl hw.ncpu | awk '{ print $2 }'`
else
NUMBER_OF_PROC=`grep ^processor $CPUINFO | wc -l`
fi
if [ ! -n "$NUMBER_OF_PROC" ]; then
echo "$FUNCNAME ERROR - number of CPUs not obtained. Use -p to define number of processes."
exit 1
fi
# use all processors if not defined otherwise
if [ ! -n "$NUMBER_OF_JOBS" ]; then
NUMBER_OF_JOBS=$NUMBER_OF_PROC
fi
if [ $NUMBER_OF_JOBS -le -1 ]; then
NUMBER_OF_JOBS=$(echo "$NUMBER_OF_PROC + $NUMBER_OF_JOBS" | bc)
if [ "$NUMBER_OF_JOBS" -lt 1 ]; then
NUMBER_OF_JOBS=1
fi
fi
if [ "$NUMBER_OF_JOBS" -gt "$NUMBER_OF_PROC" ]; then
NUMBER_OF_JOBS=$NUMBER_OF_PROC
fi
echo "Found $NUMBER_OF_PROC processors. Use $NUMBER_OF_JOBS."
echo
fi
}
########################################################
# modify defaults
########################################################
modifiy_defaults ()
{
pwd=$PWD
# argument empty?
if [ -n "${defaults}" ]; then
# check whether absolute or relative names were given
if [ -f "${pwd}/${defaults}" ]; then
defaults="${pwd}/${defaults}"
fi
# check whether defaults file exist
if [ ! -f "${defaults}" ]; then
echo Default file "$defaults" not found.
exit
fi
else
defaults=${cat12_dir}/cat_defaults.m
fi
cp ${defaults} ${defaults_tmp}
if [ "$no_surf" -eq 1 ]; then
echo "cat.output.surface = 0;" >> ${defaults_tmp}
else
echo "cat.output.surface = 1;" >> ${defaults_tmp}
fi
if [ "$no_mwp" -eq 1 ]; then
echo "cat.output.GM.mod = 0;" >> ${defaults_tmp}
echo "cat.output.WM.mod = 0;" >> ${defaults_tmp}
echo "cat.output.ROI = 0;" >> ${defaults_tmp}
echo "cat.output.bias.warped = 0;" >> ${defaults_tmp}
echo "cat.output.warps = [0 0];" >> ${defaults_tmp}
else
echo "cat.output.GM.mod = 1;" >> ${defaults_tmp}
echo "cat.output.WM.mod = 1;" >> ${defaults_tmp}
echo "cat.output.ROI = 1;" >> ${defaults_tmp}
fi
if [ "$rp" -eq 1 ]; then
echo "cat.output.GM.dartel = 2;" >> ${defaults_tmp}
echo "cat.output.WM.dartel = 2;" >> ${defaults_tmp}
fi
if [ -n "$bids_folder" ]; then
echo "cat.extopts.bids_folder = '${bids_folder}';" >> ${defaults_tmp}
echo "cat.extopts.bids_yes = 1;" >> ${defaults_tmp}
fi
if [ "$bids" -eq 1 ]; then
echo "cat.extopts.bids_yes = 1;" >> ${defaults_tmp}
fi
if [ -n "$tpm" ]; then
# check whether absolute or relative tpm was given
if [ -f "${pwd}/${tpm}" ]; then
tpm="${pwd}/${tpm}"
fi
echo "cat.opts.tpm = {'${tpm}'};" >> ${defaults_tmp}
fi
if [ -n "$add_to_defaults" ]; then
echo "${add_to_defaults}" >> ${defaults_tmp}
fi
}
########################################################
# run cat12
########################################################
run_cat12 ()
{
pwd=$PWD
# we have to go into the toolbox folder to find matlab files
cd $cwd
if [ ! -n "${LOGDIR}" ]; then
LOGDIR=$(dirname "${ARRAY[0]}")
fi
# we have to add current path if cat_batch_cat.sh was called from relative path
if [ -d ${pwd}/${spm12} ]; then
spm12=${pwd}/${spm12}
fi
export MATLABPATH=${spm12}
SIZE_OF_ARRAY="${#ARRAY[@]}"
i=0
j=0
while [ "$i" -lt "$SIZE_OF_ARRAY" ]; do
# check whether absolute or relative names were given
if [ ! -f "${ARRAY[$i]}" ]; then
if [ -f "${pwd}/${ARRAY[$i]}" ]; then
FILE="${pwd}/${ARRAY[$i]}"
fi
else
FILE=${ARRAY[$i]}
fi
# replace white spaces
FILE=$(echo "$FILE" | sed -e 's/ /\\ /g')
# check whether processed files exist if no-overwrite flag is used
if [ -n "${no_overwrite}" ]; then
dn=$(dirname "$FILE")
bn=$(basename "$FILE" |cut -f1 -d'.')
processed=`eval ls "${dn}/${no_overwrite}${bn}*" 2>/dev/null`
fi
if [ ! -n "${processed}" ]; then
if [ ! -n "${ARG_LIST[$i]}" ]; then
ARRAY2[$j]="$FILE"
else
ARRAY2[$j]="${ARRAY2[$i]} $FILE"
fi
((j++))
else
echo Skip processing of ${FILE}
fi
((i++))
done
SIZE_OF_ARRAY="${#ARRAY2[@]}"
BLOCK=$((10000* $SIZE_OF_ARRAY / $NUMBER_OF_JOBS ))
ARG_LIST=""
# split files and prepare tmp-file with filenames
TMP=/tmp/cat_$$
i=0
while [ "$i" -lt "$SIZE_OF_ARRAY" ]; do
count=$((10000* $i / $BLOCK ))
FILE="${ARRAY2[$i]}"
ARG_LIST[$count]="${ARG_LIST[$count]} '$FILE'"
# filenames have to be quoted in case of any whitespaces
if [ "$TEST" -eq 0 ]; then
echo '"'${FILE}'"' >> ${TMP}${count}
else
echo ${FILE}
fi
((i++))
done
vbmlog="${LOGDIR}/cat_${HOSTNAME}_${time}"
# if relative foldername were given we have to add the data folder because we change into cat12 folder
if [ ! -d ${LOGDIR} ]; then
vbmlog=${pwd}/${vbmlog}
fi
i=0
while [ "$i" -lt "$NUMBER_OF_JOBS" ]; do
if [ -n "${ARG_LIST[$i]}" ] && [ "$TEST" -eq 0 ]; then
j=$(($i+1))
if [ ! -n "$matlabcommand" ]; then
COMMAND="cat_batch_cat('${TMP}${i}','${defaults_tmp}')"
else
for F in ${ARG_LIST[$i]} ; do
CFILES=$CFILES","\'$F\';
done
CFILES=$(echo $CFILES | cut -c 2-);
matlabcommand2=$matlabcommand
matlabcommand2=$(echo $matlabcommand2 |sed 's/CFILES/$CFILES/g');
eval "COMMAND=\"$matlabcommand2\";"
COMMAND="try, spm; spm_get_defaults; cat_get_defaults; global defaults cat matlabbatch; $COMMAND; catch caterr, sprintf('\n%s\nVBM Preprocessing error: %s:\n%s\n', repmat('-',1,72),caterr.identifier,caterr.message,repmat('-',1,72)); for si=1:numel(caterr.stack), cat_io_cprintf('err',sprintf('%5d - %s\n',caterr.stack(si).line,caterr.stack(si).name)); end; cat_io_cprintf('err',sprintf('%s\\n',repmat('-',1,72))); exit; end; fprintf('VBM batch processing done.'); exit;";
fi
SHCOMMAND="$shellcommand ${ARG_LIST[$i]}"
echo Calculate
for F in ${ARG_LIST[$i]}; do echo $F; done
# File Output
echo > "${vbmlog}_${j}.log"
echo ---------------------------------- >> "${vbmlog}_${j}.log"
date >> "${vbmlog}_${j}.log"
echo ---------------------------------- >> "${vbmlog}_${j}.log"
echo >> "${vbmlog}_${j}.log"
echo Calling string of this batch: >> "${vbmlog}_${j}.log"
echo " $0 $paras" >> "${vbmlog}_${j}.log"
echo >> "${vbmlog}_${j}.log"
echo MATLAB command of this batch: >> "${vbmlog}_${j}.log"
echo " $COMMAND" >> "${vbmlog}_${j}.log"
echo >> "${vbmlog}_${j}.log"
if [ -n "$shellcommand" ]; then
echo Shell command of this batch: >> "${vbmlog}_${j}.log"
echo " $SHCOMMAND" >> "${vbmlog}_${j}.log"
echo >> "${vbmlog}_${j}.log"
fi
if [ ! -n "$shellcommand" ]; then
# do nohup in background or not
if [ "$fg" -eq 0 ]; then
nohup nice -n $nicelevel ${matlab} -nodisplay "$nojvm" -nosplash -r "$COMMAND" >> "${vbmlog}_${j}.log" 2>&1 &
else
nohup nice -n $nicelevel ${matlab} -nodisplay "$nojvm" -nosplash -r "$COMMAND" >> "${vbmlog}_${j}.log" 2>&1
fi
else
# do nohup in background or not
if [ "$fg" -eq 0 ]; then
nohup nice -n $nicelevel $SHCOMMAND >> "${vbmlog}_${j}.log" 2>&1 &
else
nohup nice -n $nicelevel $SHCOMMAND >> "${vbmlog}_${j}.log" 2>&1
fi
fi
echo Check "${vbmlog}_${j}.log" for logging information
echo
fi
((i++))
done
exit 0
}
########################################################
# check if matlab exist
########################################################
check_matlab ()
{
found=`which "${matlab}" 2>/dev/null`
if [ ! -n "$found" ]; then
echo $matlab not found.
exit 1
fi
}
########################################################
# help
########################################################
help ()
{
get_no_of_cpus
cat <<__EOM__
USAGE:
cat_batch_cat.sh [-m matlab_command] [-d default_file] [-l log_folder]
[-p number_of_processes] [-tpm TPM-file] [-ns] [-nm] [-rp] [-no output_pattern]
[-n nicelevel] [-s shell_command -f files_for_shell] [-c matlab_command]
[-a add_to_defaults] [-t] [-fg] [-noj] filenames|filepattern
-m <FILE> | --matlab <FILE> matlab command (matlab version) (default $matlab)
-d <FILE> | --defaults <FILE> optional default file (default ${cat12_dir}/cat_defaults.m)
-l <FILE> | --logdir directory for log-file (default $LOGDIR)
-p <NUMBER>| --processes <NUMBER> number of parallel jobs (=number of processors)
(default $NUMBER_OF_JOBS)
-np <NUMBER>| --nprocesses <NUMBER> set number of jobs by number_of_processors - number_of_processes
(=number of free processors)
-tpm <FILE> | --tpm <FILE> define own TPM
-a <STRING>| --add add option to default file
-ns | --no-surf skip surface and thickness estimation
-nm | --no-mwp skip estimating modulated and warped segmentations and ROI measures
-rp | --rp additionally estimate affine registered segmentations
-no <STRING>| --no-overwrite <STRING> do not overwrite existing results
-n <NUMBER>| --nice <NUMBER> nice level (default 0)
-s <STRING>| --shell <STRING> shell command to call other shell scripts
-f <FILES> | --files <FILES> files to process with shell command
-c <STRING>| --command <STRING> alternative matlab function that can be called such as the SANLM-filter
-t | --test do not call command, but print files to be processed
-fg | --fg do not run matlab process in background
-b | --bids use default BIDS path (i.e. '../derivatives/CAT12.x_rxxxx')
-bf <STRING>| --bids_folder <STRING> define BIDS path
-nj | --nojvm supress call of jvm using the -nojvm flag
Only one filename or pattern is allowed. This can be either a single file or a pattern
with wildcards to process multiple files.
PURPOSE:
Command line call of CAT12 segmentation
EXAMPLE
cat_batch_cat.sh ${spm12}/canonical/single_subj_T1.nii
This command will process only the single file single_subj_T1.nii.
cat_batch_cat.sh -d your_cat_defaults_file.m ${spm12}/canonical/single_subj_T1.nii
This command will process only the single file single_subj_T1.nii. The defaults defined
in your_cat_defaults_file.m is used instead of cat_defaults.m.
cat_batch_cat.sh ${spm12}/canonical/*152*.nii
Using wildcards all files containing the term "152" are processed. In this case these
are the files avg152PD.nii, avg152T1.nii, and avg152T2.nii and $NUMBER_OF_JOBS parallel
jobs are used.
cat_batch_cat.sh -no "mri/mwp1" ${spm12}/canonical/*152*.nii
Using wildcards all files containing the term "152" are processed. In this case these
are the files avg152PD.nii, avg152T1.nii, and avg152T2.nii and $NUMBER_OF_JOBS parallel
jobs are used. If processed files "mwp1*" in the subfolder "mri" are
found the processing will be skipped.
cat_batch_cat.sh -p 2 -m /usr/local/bin/matlab7 ${spm12}/canonical/*152*.nii
Using wildcards all files containing the term "152" are processed. In this case these
are the files avg152PD.nii, avg152T1.nii, and avg152T2.nii and 2 parallel jobs
jobs are used. As matlab-command /usr/local/bin/matlab7 is used.
cat_batch_cat.sh -ns -nm -rp -a "cat.extopts.WMHC = 3;" ${spm12}/canonical/single_subj_T1.nii
This command will process only the single file single_subj_T1.nii with the defaults in cat_defaults.m and
the additional option for handling WMHs as separate class. No surfaces and modulated and warped segmentations
are estimated. Only the affine registered segmentations are saved.
cat_batch_cat.sh -bids_folder ../derivatives/CAT12.8 sub*/anat/sub*T1w.nii.gz
This command will process all *.nii.gz files in the BIDS subfolders sub* with the defaults in cat_defaults.m and
will save the results as BIDS structure in '../derivatives/CAT12.8'. If the option for bids_folder is not given the
default BIDS path is '../derivatives/CAT12.x_rxxxx' where the CAT12 version is used in the path.
cat_batch_cat.sh -tpm ${cat12_dir}/templates_MNI152NLin2009cAsym/TPM_Age11.5.nii ${spm12}/canonical/single_subj_T1.nii
This command will process only the single file single_subj_T1.nii with the defaults in cat_defaults.m
and the children template that is provided with cat12.
cat_batch_cat.sh -p 2 -c "cat_vol_sanlm(struct('data',char(CFILES),'prefix','sanlm_'))" /Volumes/4TBWD/raw-cg/r[12][0-9][0-9][0-9]*.nii
This command will call the SANLM-filter using the given files, that have to be indicated with CFILES
as first argument. As prefix 'sanlm_' is used.
INPUT:
analyze or nifti files
OUTPUT:
segmented images according to settings in cat_defaults.m
${LOGDIR}/cat_${HOSTNAME}_${time}.log for log information
USED FUNCTIONS:
cat_batch_cat.m
CAT12 toolbox
SPM12
SETTINGS
matlab command: $matlab
This script was written by Christian Gaser ([email protected]).
__EOM__
}
########################################################
# call main program
########################################################
main ${1+"$@"}