]> Creatis software - clitk.git/blob - scripts/create_midP_masks-2.0.sh
corrections in mid-P scripts
[clitk.git] / scripts / create_midP_masks-2.0.sh
1 #! /bin/bash 
2   
3 ###############################################################################
4 #
5 # FILE: create_midP-2.0.sh
6 # AUTHOR: RĂ´mulo Pinho 05/08/2011
7 #
8 # Version 2.0 of the create_midP_masks.sh script. The most relevant changes are:
9 #   * creation of bands around input and output image regions to try to improve 
10 #   the registration along lung boundaries (naturally, it depends on the quality
11 #   of motion mask generation).
12 #   * some steps are now in different modules, to facilitate re-use (see "includes" section).
13 #   * minor modifications on output file names.
14 #   * attempt to simplify the code a bit.
15 #
16 ###############################################################################
17
18 source `dirname $0`/midp_common.sh
19
20 extract_patient()
21 {
22   echo "$phase_file -> Extracting patient..."
23   clitkExtractPatient -i $phase_file -o $mask_dir_tmp/patient_mask_$phase_nb.mhd --noAutoCrop -a $afdb_file $ExtractPatientExtra
24 #   abort_on_error clitkExtractPatient $?
25
26   clitkSetBackground -i $phase_file -o $mask_dir_tmp/patient_$phase_nb.mhd --mask $mask_dir_tmp/patient_mask_$phase_nb.mhd --outsideValue -1000
27 #   abort_on_error clitkSetBackground $?
28 }
29
30 extract_bones()
31 {
32   if [ x = x$ExtractBonesLower1 ]; then
33     ExtractBonesLower1=120
34   fi
35   if [ x = x$ExtractBonesLower2 ]; then
36     ExtractBonesLower2=80
37   fi
38   echo "$phase_file -> Extracting bones..."
39   clitkImageConvert -i $phase_file -o $mask_dir_tmp/float_$phase_nb.mhd -t float
40   clitkExtractBones -i $mask_dir_tmp/float_$phase_nb.mhd -o $mask_dir_tmp/bones_$phase_nb.mhd -a $afdb_file --lower1 $ExtractBonesLower1 --upper1 2000 --lower2 $ExtractBonesLower2 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
41 }
42
43 extract_lungs()
44 {
45   echo "$phase_file -> Extracting lungs..."  
46   clitkExtractLung -i $phase_file -o $mask_dir_tmp/lungs_$phase_nb.mhd -a $afdb_file --noAutoCrop --doNotSeparateLungs
47 }
48
49
50
51 resample()
52 {
53   echo "$phase_file -> Resampling..."
54   clitkResampleImage -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/patient_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
55   clitkResampleImage -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/lungs_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
56 }
57
58 compute_motion_mask()
59 {
60   if [ x = x$MotionMaskOffsetDetect ]; then
61     MotionMaskOffsetDetect="0,-5,0"
62   fi
63   if [ x = x$FillingLevel ]; then
64     FillingLevel=94
65   fi
66
67   clitkMotionMask -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/mm_$phase_nb.mhd --featureLungs $mask_dir_tmp/lungs_$phase_nb.mhd --upperThresholdLungs -400 --fillingLevel $FillingLevel --offsetDetect $MotionMaskOffsetDetect --pad --writeFeature=$mask_dir_tmp/feature_$phase_nb.mhd $MotionMaskExtra 
68   #--monitor=$mask_dir_tmp/monitor_$phase_nb.mhd
69 }
70
71 create_banded_mask()
72 {
73   input=$1
74   input_mask=$2
75   output=$3
76   output_mask=$4
77   radius=$5
78
79   input_dir=`dirname $input`
80   input_base=`basename $input`
81
82   # first band
83   clitkMorphoMath -i $input_mask -o $input_dir/extra1_$input_base --type 1 --radius $radius
84   clitkImageArithm -i $input_dir/extra1_$input_base -j $input_mask -o $input_dir/band1_$input_base -t 7
85   clitkBinarizeImage -i $input_dir/band1_$input_base -o $input_dir/band1_$input_base -l 1 -u 1 --fg 100 --mode both
86   clitkImageConvert -i $input_dir/band1_$input_base -o $input_dir/short_band1_$input_base -t short
87   
88   # second band
89   clitkMorphoMath -i $input_dir/extra1_$input_base -o $input_dir/extra2_$input_base --type 1 --radius $radius
90   clitkImageArithm -i $input_dir/extra2_$input_base -j $input_dir/extra1_$input_base -o $input_dir/band2_$input_base -t 7
91   clitkBinarizeImage -i $input_dir/band2_$input_base -o $input_dir/band2_$input_base -l 1 -u 1 --fg 200 --mode both
92   clitkImageConvert -i $input_dir/band2_$input_base -o $input_dir/short_band2_$input_base -t short
93   
94   # combine bands with masks
95   clitkImageArithm -i $input_mask -j $input_dir/band1_$input_base -o $output_mask -t 0
96   clitkImageArithm -i $output_mask -j $input_dir/band2_$input_base -o $output_mask -t 0
97   # combine bands with image
98   clitkCombineImage -i $input_dir/short_band1_$input_base -j $input -m $input_dir/band1_$input_base -o $output
99   clitkCombineImage -i $input_dir/short_band2_$input_base -j $output -m $input_dir/band2_$input_base -o $output
100
101   # clean-up
102   rm `echo $input_dir/extra?_$input_base | sed 's:.mhd:.*:g'`
103   rm `echo $input_dir/band?_$input_base | sed 's:.mhd:.*:g'`
104   rm `echo $input_dir/short_band?_$input_base | sed 's:.mhd:.*:g'`
105 }
106
107 create_registration_masks()
108 {
109   # extract inside and outside lung regions from the patient image, 
110   # using the motion mask computed previously
111   echo "$phase_file -> Setting Background..."
112   clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/inside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200
113   clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/outside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200 --fg
114
115   # the registration masks for inside (and outside) region correspond
116   # to the motion mask (and its complement) plus extra grey value bands,
117   # obtained with morphological dilations.
118   # 
119   echo "$phase_file -> Creating registration masks..."
120   # inside
121   create_banded_mask $mask_dir_tmp/inside_$phase_nb.mhd $mask_dir_tmp/mm_$phase_nb.mhd $mask_dir_tmp/banded_inside_$phase_nb.mhd $mask_dir_tmp/mask_inside_$phase_nb.mhd 4
122   # outside 
123   clitkExtractPatient -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/mm_outside_$phase_nb.mhd --noAutoCrop
124   create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/mm_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/mask_outside_$phase_nb.mhd 4
125 }
126
127 mm_preprocessing()
128 {
129   extract_patient
130   # extract_bones
131   extract_lungs
132   # remove_tmp_masks 1
133   resample
134 }
135
136 mm_postprocessing()
137 {
138   # remove_tmp_masks 2
139   # remove_tmp_masks 3
140   create_registration_masks
141 }
142
143 motion_mask()
144 {
145   #set cmd line variables
146   mhd4d=$1
147   resample_spacing=$2
148   resample_algo=$3
149
150   dir=`dirname $1`
151   cd $dir
152     
153   # import variables specific to each patient
154   if test -e ./variables; then
155     source ./variables
156   fi
157
158   #set other global variables
159   mask_dir="MASK-${resample_spacing}mm-$resample_algo"
160   mask_dir_tmp="tmp.$mask_dir"
161   extract_4d_phases $mhd4d
162
163   echo
164   echo "------------ Motion mask from create_midP_masks.sh ------------"
165   start=`date`
166   echo "start: $start"
167   echo
168
169   # the motion masks are first created in a tmp directory. this directory is 
170   # later going to be renamed to the final motion mask directory. concurrent
171   # executions trying to create the same set of masks will be blocked until
172   # the first execution finishes. naturally, these other executions will not
173   # recreate the masks. so first we try to create the tmp directory. 
174   # if the creation fails, it means that another execution is
175   # already creating the masks, so this execution will be blocked. the
176   # execution is unblocked only when the creation of masks is finished and
177   # the mask directory is renamed.
178   #
179   # ATTENTION: RP - 08/02/2011
180   # robustness issue: tmp directory may exist but may be empty or 
181   # incomplete. the solution is to check per file, but I'll leave it like 
182   # this for the moment.
183   do_mm=0
184   if [ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]; then
185     mkdir $mask_dir_tmp 2> /dev/null
186     return_mkdir=$?
187     if [ $return_mkdir == 0 ]; then
188       do_mm=1 
189     else
190       while [[ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]]; do
191         echo "waiting creation of motion masks..."
192         sleep 2
193       done
194       echo "finished waiting"
195     fi  
196   fi
197   
198 #   do_mm=1
199 #   mask_dir_tmp=$mask_dir
200   if [ $do_mm == 1 ]; then
201     mask_log_dir=$mask_dir_tmp/LOG
202     mkdir -p $mask_log_dir
203
204     # multi-threaded pre-processing for motion mask calcs
205     pids=( )
206     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
207       phase_nb=${phase_nbs[$i]}
208       phase_file=${phase_files[$i]}
209       afdb_file=`echo $phase_file | sed 's/mhd/afdb/'`
210
211       check_threads $MAX_THREADS
212       mm_preprocessing &
213       pids=( "${pids[@]}" "$!" )
214     done
215
216     wait_pids ${pids[@]}
217     for ret in $ret_codes; do
218       abort_on_error mm_preprocessing $ret clean_up_masks
219     done
220
221     # single-threaded motion mask calc
222     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
223       phase_nb=${phase_nbs[$i]}
224       phase_file=${phase_files[$i]}
225
226       check_threads 1
227       echo "$phase_file -> Computing motion mask..."
228       compute_motion_mask > $mask_log_dir/motion_mask_$phase_file.log
229       abort_on_error compute_motion_mask $? clean_up_masks
230     done
231
232     # multi-threaded post-processing of motion mask calcs
233     pids=( )
234     for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
235       phase_nb=${phase_nbs[$i]}
236       phase_file=${phase_files[$i]}
237
238       check_threads $MAX_THREADS 
239       mm_postprocessing &
240       pids=( "${pids[@]}" "$!" )
241     done
242   
243     wait_pids ${pids[@]}
244     for ret in $ret_codes; do
245       abort_on_error mm_postprocessing $ret clean_up_masks
246     done
247
248
249     # rename tmp mask directory after mask creation
250     check_threads 1
251     mv -f $mask_dir_tmp $mask_dir
252   fi
253
254   echo
255   echo "-------- Motion mask done ! ---------"
256   end=`date`
257   echo "start: $start"
258   echo "end: $end"
259   echo
260 }
261
262
263 #################
264 # main  #
265 #################
266
267 if [ $# != 3 ]; then
268   echo "Usage: $0 CT_4D RESAMPLE_SPACING RESAMPLE_ALGORITHM"
269   exit -1
270 fi
271
272 #
273 # variables exported in this scope
274 #
275 # mask_dir: directory where all masks are kept
276 #
277
278 if [ $1 != "using-as-lib" ]; then
279   motion_mask $1 $2 $3
280 fi