From 34af28a29bf9c7816747f8507c4a9985354811f8 Mon Sep 17 00:00:00 2001 From: Romulo Pinho Date: Fri, 5 Aug 2011 11:15:31 +0200 Subject: [PATCH] new midP related scripts - they are also installed when make-installing --- CMakeLists.txt | 17 + scripts/common.sh | 106 +++++- scripts/create_mhd_3D.sh | 50 +++ scripts/create_mhd_4D-2.0.sh | 49 +++ scripts/create_mhd_4D_pattern.sh | 60 ++++ scripts/create_midP-2.0.sh | 209 ++++++++++++ scripts/create_midP.sh | 535 +++++++++++++++++++++++++++++++ scripts/create_midP_masks-2.0.sh | 258 +++++++++++++++ scripts/create_midP_masks.sh | 4 +- scripts/pts_to_landmarks.sh | 27 ++ scripts/registration.sh | 123 +++++++ 11 files changed, 1431 insertions(+), 7 deletions(-) create mode 100755 scripts/create_mhd_3D.sh create mode 100755 scripts/create_mhd_4D-2.0.sh create mode 100755 scripts/create_mhd_4D_pattern.sh create mode 100755 scripts/create_midP-2.0.sh create mode 100755 scripts/create_midP.sh create mode 100755 scripts/create_midP_masks-2.0.sh create mode 100755 scripts/pts_to_landmarks.sh create mode 100755 scripts/registration.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fe2e34..abd2d3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,3 +109,20 @@ ENDIF(CLITK_BUILD_VV) IF(BUILD_TESTING) ADD_SUBDIRECTORY(tests) ENDIF(BUILD_TESTING) + +#========================================================= +# Install scripts when running make install +SET(SCRIPTS + scripts/common.sh + scripts/registration.sh + scripts/create_midP.sh + scripts/create_midP-2.0.sh + scripts/create_mhd_4D.sh + scripts/create_mhd_4D_pattern.sh + scripts/create_midP_masks.sh + scripts/create_midP_masks-2.0.sh + scripts/pts_to_landmarks.sh +) + +INSTALL (FILES ${SCRIPTS} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE) + diff --git a/scripts/common.sh b/scripts/common.sh index e06bf25..73d1787 100755 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -1,14 +1,110 @@ -#! /bin/sh +#! /bin/sh +x +############################################################################### +# +# FILE: common.sh +# AUTHOR: Rômulo Pinho 05/08/2011 +# +# Helper file with many functions used in the midP scripts. +# +############################################################################### -MAX_THREADS=2 +# block execution untill the number of threads (jobs) launched by the +# current process is below the given number of threads. +MAX_THREADS=2 check_threads() { - while [[ $(jobs -p | wc -l) -ge $1 ]]; do - jobs - sleep 10 + nbth=$1 + while [[ $(jobs -p | wc -l) -ge $nbth ]]; do + jobs + sleep 10 + done +} + +# +# receive a 4D file and and extract the corresponding phase numbers +# export the variables containing each of the extracted data +# +extract_4d_phase_numbers() +{ + mhd4d=$1 + + nb_phases=${#phase_files[@]} + + # get everything except numbers and punctuation + cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[^0-9[:punct:]]*" | sort -u > /tmp/patterns.txt + + # find which patterns have the phases connected to it + patterns=`cat /tmp/patterns.txt` + if [ -z "$patterns" ]; then + phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep "[0-9]\+"` ) + else + for i in $patterns; do + + # check if the pattern appears before the phase number + nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | sort -u | wc -l` + if [ $nb_phases_found == $nb_phases ]; then + # keep only what identifies the phase number + phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` ) + break + fi + + # check if the pattern appears after the phase number + nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | sort -u | wc -l` + if [ $nb_phases_found == $nb_phases ]; then + # keep only what identifies the phase number + phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` ) + break + fi + done + fi + + echo "Phase numbers are ${phase_nbs[@]}" + rm /tmp/patterns.txt } +# +# receive a 4D file and extract the corresponding phase files, +# and phase numbers. +# export the variables containing each of the extracted data +# +extract_4d_phases() +{ + mhd4d=$1 + + echo "4D file is $mhd4d" + + # array of phase files + phase_files=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:'` ) + echo "Phase files are ${phase_files[@]}" + + extract_4d_phase_numbers $mhd4d +} + +# +# receive a 4D file and the reference phase number as input +# and extract the corresponding phase files, phase numbers, +# and reference phase file. +# +# export the variables containing each of the extracted data +# +extract_4d_phases_ref() +{ + extract_4d_phases $1 + + # reference phase file + ref_phase_file=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | grep $2` + echo "Reference phase is $ref_phase_file" + + # reference phase number + for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do + ref_phase_nb=`echo ${phase_nbs[$i]} | grep $2` + if [ -n "$ref_phase_nb" ]; then + echo "Reference phase number is $ref_phase_nb" + break + fi + done +} diff --git a/scripts/create_mhd_3D.sh b/scripts/create_mhd_3D.sh new file mode 100755 index 0000000..fbb9760 --- /dev/null +++ b/scripts/create_mhd_3D.sh @@ -0,0 +1,50 @@ +#!/bin/sh + + +################################################################################# +# create_mhd_3D argument : {image data} raw_image nom_fichier_de_sortie # +################################################################################# +if [ $# -lt 1 ] +then + echo "Usage: create_mhd_3D.sh dimx dimy dimz spcx spcy spcz offx offy offz pixel_type raw_image_file output_file" + echo "dim*: dimensions of the image" + echo "spc*: pixel spacing along each dimension" + echo "off*: offset along each dimension" + echo "pixel_type: CHAR, UCHAR, SHORT, USHORT, FLOAT" + echo "raw_image_file: image to be referenced by the mhd file created" + echo "output_file: mhd to be created" + exit 1 +fi + +# can point to existing raw files +n=`ls ${11} | wc -l` +if [ $n -eq 0 ] +then + echo "${11} does not exist. Cannot create mhd file." + exit +fi + +# check if the raw file has the "raw" extension +n=`ls ${11} | grep .raw | wc -l` +if [ $n -eq 0 ] +then + # change extension to raw + raw_base=`echo ${11} | cut -d . -f 1`; + raw_file=$raw_base".raw"; + mv ${11} $raw_file +else + raw_file=${11} +fi + +# create file (with some default values...) +echo "NDims = 3" > ${12} +echo "TransformMatrix = 1 0 0 0 1 0 0 0 1" >> ${12} +echo "Offset = " $7 $8 $9 >> ${12} +echo "CenterOfRotation = 0 0 0" >> ${12} +echo "AnatomicalOrientation = RAI" >> ${12} +echo "ElementSpacing = " $4 $5 $6 >> ${12} +echo "DimSize = " $1 $2 $3 >> ${12} +echo "ElementType = MET_"${10} >> ${12} +echo "ElementDataFile = " $raw_file >> ${12} + + diff --git a/scripts/create_mhd_4D-2.0.sh b/scripts/create_mhd_4D-2.0.sh new file mode 100755 index 0000000..c10e098 --- /dev/null +++ b/scripts/create_mhd_4D-2.0.sh @@ -0,0 +1,49 @@ +#!/bin/sh +x + + +write_mhd_4D() +{ + cat $orig | sed "s/NDims = .*/NDims = 4/ + s/TransformMatrix = .*/TransformMatrix = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1/ + /Offset/ s/.*/& 0/ + /CenterOfRotation/ s/.*/& 0/ + s/AnatomicalOrientation = .*/AnatomicalOrientation = ????/ + /ElementSpacing/ s/.*/& 1/ + /DimSize/ s/.*/& $nbph/ + s/ElementDataFile = .*/ElementDataFile = LIST/" > "$1/$file_name_4D" + + for ph in $listph + do + phase=`basename $ph` + echo "$phase" >> "$1/$file_name_4D" + done +} + +################################################# +# create_mhd_4D argument : repertoire # +################################################# +if [ $# -lt 1 ] +then + echo "Usage: create_mhd_4D.sh DIRECTORY" + exit 1 +fi + +dirname=`dirname $1` +pattern=`basename $1` + +list_phase_file=`ls -1 $1*[0-9].mhd` +nb_phase_file=`ls -1 $1*[0-9].mhd | wc -l` +if [ $nb_phase_file = 0 ] +then + echo "Error: no phase found" + exit 1 +fi + +nbph=$nb_phase_file +orig=`echo $list_phase_file | cut -f 1 -d ' '` +listph=`echo $list_phase_file | sed 's:\.mhd:\.raw:g'` + +file_name_4D=`echo "${pattern}4D.mhd"` + +write_mhd_4D $dirname +echo "$dirname/$file_name_4D" diff --git a/scripts/create_mhd_4D_pattern.sh b/scripts/create_mhd_4D_pattern.sh new file mode 100755 index 0000000..4d64347 --- /dev/null +++ b/scripts/create_mhd_4D_pattern.sh @@ -0,0 +1,60 @@ +#!/bin/sh +x + +############################################################################### +# +# FILE: create_mhd_pattern.sh +# AUTHOR: Rômulo Pinho 05/08/2011 +# +# Similar to create_mhd_4D.sh, but receives a pattern as input. +# +# Example: +# create_mhd_pattern.sh "/all_my_phases_start_like_this_" +# +############################################################################### + +write_mhd_4D() +{ + cat $orig | sed "s/NDims = .*/NDims = 4/ + s/TransformMatrix = .*/TransformMatrix = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1/ + /Offset/ s/.*/& 0/ + /CenterOfRotation/ s/.*/& 0/ + s/AnatomicalOrientation = .*/AnatomicalOrientation = ????/ + /ElementSpacing/ s/.*/& 1/ + /DimSize/ s/.*/& $nbph/ + s/ElementDataFile = .*/ElementDataFile = LIST/" > "$1/$file_name_4D" + + for ph in $listph + do + phase=`basename $ph` + echo "$phase" >> "$1/$file_name_4D" + done +} + +################################################# +# create_mhd_4D argument : repertoire # +################################################# +if [ $# -lt 1 ] +then + echo "Usage: $0 PATTERN" + exit 1 +fi + +dirname=`dirname $1` +pattern=`basename $1` + +list_phase_file=`ls -1 $1*[0-9].mhd` +nb_phase_file=`ls -1 $1*[0-9].mhd | wc -l` +if [ $nb_phase_file = 0 ] +then + echo "Error: no phase found" + exit 1 +fi + +nbph=$nb_phase_file +orig=`echo $list_phase_file | cut -f 1 -d ' '` +listph=`echo $list_phase_file | sed 's:\.mhd:\.raw:g'` + +file_name_4D=`echo "${pattern}4D.mhd"` + +write_mhd_4D $dirname +echo "$dirname/$file_name_4D" diff --git a/scripts/create_midP-2.0.sh b/scripts/create_midP-2.0.sh new file mode 100755 index 0000000..8b53008 --- /dev/null +++ b/scripts/create_midP-2.0.sh @@ -0,0 +1,209 @@ +#!/bin/sh -x + +############################################################################### +# +# FILE: create_midP-2.0.sh +# AUTHOR: Rômulo Pinho 05/08/2011 +# +# Version 2.0 of the create_midP.sh script. The most relevant changes are: +# * receives a .conf file as input, with variables related to the registration +# parameters and to paramters of the script itself (see accompanying midp_template.conf) +# for details. +# * separates execution steps: it's now possible to choose which operation to execute +# (mask, registration, midp, or all). +# * some steps are now in different modules, to facilitate re-use (see "includes" section). +# * minor modifications on output file names. +# * attempt to simplify the code a bit. +# +############################################################################### + +######################### includes + +source `dirname $0`/create_midP_masks-2.0.sh using-as-lib 2 nn +source `dirname $0`/registration.sh +source `dirname $0`/common.sh + +registration() +{ + echo + echo "----------- Registration ------------" + start=`date` + echo "start: $start" + echo + + mkdir -p $vf_dir + mkdir -p $output_dir + + # banded images may be created as separate files, + # with the specified preffix, which is interesting for debugging. + # if blank, it means that the original images (those without bands) + # will be used (see create_midP_masks-2.0.sh for details). + banded="banded_" + + # params read from conf file + params="$nb_iter $nb_samples $sampling_algo $nb_hist_bins $nb_levels $bspline_spacing $metric $optimizer $interpolator" + + # register all phases to the reference + for i in $( seq 0 $((${#phase_files[@]} - 1))); do + phase_file=${phase_files[$i]} + phase_nb=${phase_nbs[$i]} + + if [ "$phase_nb" != "$ref_phase_nb" ]; then + # inside params + reference_in=$mask_dir/${banded}inside_$ref_phase_nb.mhd + target_in=$mask_dir/${banded}inside_$phase_nb.mhd + mask_ref_in=$mask_dir/mask_inside_$ref_phase_nb.mhd + mask_targ_in=$mask_dir/mask_inside_$phase_nb.mhd + vf_in=$vf_dir/vf_inside_${ref_phase_nb}_$phase_nb.mhd + result_in=$output_dir/result_inside_${ref_phase_nb}_$phase_nb.mhd + log_in=$log_dir/log_inside_${ref_phase_nb}_$phase_nb.log + + # outside params + reference_out=$mask_dir/${banded}outside_$ref_phase_nb.mhd + target_out=$mask_dir/${banded}outside_$phase_nb.mhd + mask_ref_out=$mask_dir/mask_outside_$ref_phase_nb.mhd + mask_targ_out=$mask_dir/mask_outside_$phase_nb.mhd + vf_out=$vf_dir/vf_outside_$ref_phase_nb\_$phase_nb.mhd + result_out=$output_dir/result_outside_$ref_phase_nb\_$phase_nb.mhd + log_out=$log_dir/log_outside_${ref_phase_nb}_$phase_nb.log + + # registration + if [ "$method" == "blutdir" ]; then + registration_blutdir $reference_in $target_in $mask_ref_in $mask_targ_in $vf_in $result_in $params $log_in + registration_blutdir $reference_out $target_out $mask_ref_out $mask_targ_out $vf_out $result_out $params $log_out + elif [ "$method" == "elastix" ]; then + registration_elastix $reference_in $target_in $mask_ref_in $mask_targ_in $vf_in $result_in $params $log_in + registration_elastix $reference_out $target_out $mask_ref_out $mask_targ_out $vf_out $result_out $params $log_out + fi + + # combine in and out vf + motion_mask=$mask_dir/mm_$phase_nb.mhd + vf_result=$vf_dir/vf_${ref_phase_nb}_$phase_nb.mhd + clitkCombineImage -i $vf_in -j $vf_out -m $motion_mask -o $vf_result + clitkZeroVF -i $vf_in -o vf_zero.mhd + clitkCombineImage -i $vf_result -j vf_zero.mhd -m $patient_mask -o $vf_result + rm vf_zero.* + + # save for later... + vf_ref=$vf_in + fi + done + + # create (zero) vf from reference to reference + clitkZeroVF -i $vf_ref -o $vf_dir/vf_${ref_phase_nb}_${ref_phase_nb}.mhd + + # create 4D vf + create_mhd_4D_pattern.sh $vf_dir/vf_${ref_phase_nb}_ + + echo + echo "-------- Registration done ! --------" + end=`date` + echo "start: $start" + echo "end: $end" + echo +} + +midp() +{ + echo + echo "----------- Mid-position ------------" + start=`date` + echo "start: $start" + echo + + mkdir -p $midp_dir + + ########### calculate the midp wrt the reference phase + phase_nb=$ref_phase_nb + echo "Calculating midp_$phase_nb.mhd..." + vf_midp=$midp_dir/vf_$phase_nb\_midp.mhd + midp=$midp_dir/midp_$phase_nb.mhd + # average the vf's from reference phase to phase + clitkAverageTemporalDimension -i $vf_dir/vf_${ref_phase_nb}_4D.mhd -o $vf_midp + # invert the vf (why?) + clitkInvertVF -i $vf_midp -o $vf_midp + # create the midp by warping the reference phase with the reference vf + clitkWarpImage -i $ref_phase_file -o $midp --vf=$vf_midp -s 1 + + ref_vf_midp=$vf_midp + ref_midp=$midp + clitkImageConvert -i $ref_midp -o $ref_midp -t float + + ########### calculate the midp wrt the other phases + for i in $( seq 0 $((${#phase_files[@]} - 1))); do + phase_file=${phase_files[$i]} + phase_nb=${phase_nbs[$i]} + vf_midp=$midp_dir/vf_$phase_nb\_midp.mhd + midp=$midp_dir/midp_$phase_nb.mhd + + if [ "$phase_nb" != "$ref_phase_nb" ]; then + echo "Calculating midp_$phase_nb.mhd..." + # calculate vf from phase to midp, using the vf from reference phase to midp (-i) + # and the vf from reference phase to phase (-j) + clitkComposeVF -i $ref_vf_midp -j $vf_dir/vf_$ref_phase_nb\_$phase_nb.mhd -o $vf_midp + clitkWarpImage -i $phase_file -o $midp --vf=$vf_midp -s 1 + clitkImageConvert -i $midp -o $midp -t float + fi + done + + create_mhd_4D_pattern.sh $midp_dir/midp_ + echo "Calculating midp_avg.mhd..." + clitkAverageTemporalDimension -i $midp_dir/midp_4D.mhd -o $midp_dir/midp_avg.mhd + echo "Calculating midp_med.mhd..." + clitkMedianTemporalDimension -i $midp_dir/midp_4D.mhd -o $midp_dir/midp_med.mhd + + # clean-up + rm $midp_dir/vf_* + + echo + echo "-------- Mid-position done ! --------" + end=`date` + echo "start: $start" + echo "end: $end" + echo +} + + + +######################### main + +if [ $# != 3 ]; then + echo "Usage: create_midP-2.0.sh CT_4D REF_PHASE CONF_FILE" + exit -1 +fi + +echo +echo "--------------- START ---------------" +begining=`date --rfc-3339=seconds` +# echo "beginning: $begining" +echo + +# variable declarations +mhd4d=$1 +ref_phase=$2 +conf=$3 +source $conf + +mkdir -p $log_dir +mask_dir="MASK-${mask_interpolation_spacing}mm-$mask_interpolation_algorithm" + +extract_4d_phases_ref $mhd4d $ref_phase + +if [ "$step" == "mask" -o "$step" == "all" ]; then + motion_mask $mhd4d $mask_interpolation_spacing $mask_interpolation_algorithm +fi + +if [ "$step" == "registration" -o "$step" == "all" ]; then + registration +fi + +if [ "$step" == "midp" -o "$step" == "all" ]; then + midp +fi + +echo +echo "---------------- END ----------------" +terminating=`date --rfc-3339=seconds` +echo "beginning: $begining" +echo "terminating: $terminating" +echo diff --git a/scripts/create_midP.sh b/scripts/create_midP.sh new file mode 100755 index 0000000..164fb5e --- /dev/null +++ b/scripts/create_midP.sh @@ -0,0 +1,535 @@ +#!/bin/sh -x + +################################################################# +# create_MidP arguments : CT_4D.mhd ref_phase spacing # +################################################################# +source `dirname $0`/common.sh + +extract_patient() +{ + echo "$image_name -> Extracting patient..." + $CLITK/clitkExtractPatient -i $image_name -o MASK/patient_$image_name --noAutoCrop + $CLITK/clitkBinarizeImage -i MASK/patient_$image_name -o MASK/patient_$image_name -l 1 -u 1 --mode=BG + $CLITK/clitkSetBackground -i $image_name -o MASK/patient_only_$image_name --mask MASK/patient_$image_name --outsideValue -1000 +} + +extract_bones() +{ + echo "$image_name -> Extracting bones..." + $CLITK/clitkImageConvert -i $image_name -o MASK/float_$image_name -t float + $CLITK/clitkExtractBones -i MASK/float_$image_name -o MASK/bones_$image_name --lower1 120 --upper1 2000 --lower2 70 --upper2 2000 --smooth --time 0.0625 --noAutoCrop + $CLITK/clitkMorphoMath -i MASK/bones_$image_name -o MASK/bones_$image_name --type 2 --radius 4,4,2 +} + +resample() +{ + echo "$image_name -> Resampling..." + $CLITK/clitkResampleImage -i MASK/patient_$image_name -o MASK/patient_$image_name --spacing $spacing + $CLITK/clitkResampleImage -i MASK/patient_only_$image_name -o MASK/patient_only_$image_name --spacing $spacing + #$CLITK/clitkResampleImage -i MASK/bones_$image_name -o MASK/bones_$image_name --like MASK/patient_only_$image_name +} + +compute_motion_mask() +{ +# $CLITK/clitkMotionMask -i MASK/patient_only_$image_name -o MASK/mm_$image_name --featureBones=MASK/bones_$image_name --upperThresholdLungs -400 --fillingLevel 94 --offsetDetect 0,-5,0 --pad --writeFeature=MASK/feature_$image_name --writeEllips=MASK/inital_ellipse_$image_name --writeGrownEllips=MASK/growing_ellipse_$image_name; +$CLITK/clitkMotionMask -i MASK/patient_only_$image_name -o MASK/mm_$image_name --upperThresholdLungs -400 --fillingLevel 94 --offsetDetect 0,-5,0 --pad --writeFeature=MASK/feature_$image_name --writeEllips=MASK/inital_ellipse_$image_name --writeGrownEllips=MASK/growing_ellipse_$image_name; +} + +set_background() +{ + echo "$image_name -> Setting Background..." + $CLITK/clitkSetBackground -i MASK/patient_only_$image_name -o MASK/inside_$image_name --mask MASK/mm_$image_name --outsideValue -1200 + $CLITK/clitkSetBackground -i MASK/patient_only_$image_name -o MASK/outside_$image_name --mask MASK/mm_$image_name --outsideValue -1200 --fg +} + +create_registration_masks() +{ + echo "$image_name -> Creating registration masks..." + $CLITK/clitkMorphoMath -i MASK/mm_$image_name -o MASK/regmask_in_$image_name --type 1 --radius 8 + $CLITK/clitkExtractPatient -i MASK/outside_$image_name -o MASK/regmask_out_$image_name --noAutoCrop + $CLITK/clitkMorphoMath -i MASK/regmask_out_$image_name -o MASK/regmask_out_$image_name --type 1 --radius 8 +} + +remove_files() +{ + echo "Removing temporary files..." + image_name_base=`echo $image_name | sed 's/mhd//'` + case $1 in + 1) + rm MASK/float_$image_name_base*;; + 2) + rm MASK/bones_$image_name_base*;; + 3) + rm MASK/patient_only_$image_name_base*;; + 4) + #rm MASK/patient_$image_name_base* + #rm MASK/mm_$image_name_base* + rm -f $vf_dir/vf_tmp_in_${ref}_${phase}.* + rm -f $vf_dir/vf_tmp_out_${ref}_${phase}.* + #rm MASK/regmask_in_$image_name_base* + #rm MASK/regmask_out_$image_name_base* + ;; + 5) +# rm -f coeff_* + #rm $vf_dir/vf_in_* + #rm $vf_dir/vf_out_* +# rm MASK/regmask_* +# rm MASK/mm_* + ;; + 6) + ;; + #rm -f $vf_dir/_4D.* + #rm -f $vf_dir/vf_MIDP_${ref}.* + #rm -f $vf_dir/vf_${ref}_MIDP.*;; + 7) + ;; #rm $vf_dir/vf_MIDP_${phase}.*;; + 8) + rm $vf_dir/*.txt + rm $vf_dir/*.log + esac +} + +mm_preprocessing() +{ + extract_patient + #extract_bones + remove_files 1 + resample +} + +mm_postprocessing() +{ + remove_files 2 + set_background + remove_files 3 + create_registration_masks +} + +# mm_workflow() +# { +# extract_patient +# extract_bones +# remove_files 1 +# resample +# echo "$image_name -> Computing motion mask..." +# compute_motion_mask >> LOG/motion_mask_$image_name.log +# remove_files 2 +# set_background +# remove_files 3 +# create_registration_masks +# } + +motion_mask() +{ + echo + echo "------------ Motion mask ------------" + start=`date` + echo "start: $start" + echo + mkdir -p "MASK" + rm -f "LOG/motion_mask*.log" + regmask_in_list="" + regmask_out_list="" + reg_in_list="" + reg_out_list="" + + # multi-threaded pre-processing for motion mask calcs + for phase in $phase_list + do + image_name=`echo $phase | sed 's/raw/mhd/'` + check_threads $MAX_THREADS + #mm_preprocessing & + done + + # single-threaded motion mask calc + check_threads 1 + for phase in $phase_list + do + image_name=`echo $phase | sed 's/raw/mhd/'` + + echo "$image_name -> Computing motion mask..." + #compute_motion_mask >> LOG/motion_mask_$image_name.log + done + + # multi-threaded post-processing of motion mask calcs + for phase in $phase_list + do + image_name=`echo $phase | sed 's/raw/mhd/'` + check_threads $MAX_THREADS + #mm_postprocessing & + regmask_in_list="$regmask_in_list regmask_in_$image_name" + regmask_out_list="$regmask_out_list regmask_out_$image_name" + reg_in_list="$reg_in_list inside_$image_name" + reg_out_list="$reg_out_list outside_$image_name" + done + + wait + echo + echo "-------- Motion mask done ! ---------" + end=`date` + echo "start: $start" + echo "end: $end" + echo +} + +compute_BLUTDIR() +{ + ########## register in ########## + for reg_in in $reg_in_list + do + if [ ! -z `echo $reg_in | grep "$phase"` ] + then + target_in=$reg_in + fi + done + echo "Computing BLUTDIR $reference_in -> $target_in ..." + #$CLITK/clitkBLUTDIR --reference="MASK/$reference_in" --target="MASK/$target_in" --output="MASK/reg_$target_in" --referenceMask="MASK/$reference_mask_in" --vf="$vf_dir/vf_in_${ref}_${phase}.mhd" $coeff_in_ini --coeff="$coeff_dir/coeff_in_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log + $CLITK/clitkBLUTDIR --reference="MASK/$reference_in" --target="MASK/$target_in" --output="MASK/reg_$target_in" --referenceMask="MASK/$reference_mask_in" --vf="$vf_dir/vf_in_${ref}_${phase}.mhd" --coeff="$coeff_dir/coeff_in_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log + coeff_in_ini="--initCoeff=$coeff_dir/coeff_in_${ref}_${phase}.mhd" + ########## register out ########## + for reg_out in $reg_out_list + do + if [ ! -z `echo $reg_out | grep "$phase"` ] + then + target_out=$reg_out + fi + done + echo "Computing BLUTDIR $reference_out -> $target_out ..." + #$CLITK/clitkBLUTDIR --reference="MASK/$reference_out" --target="MASK/$target_out" --output="MASK/reg_$target_out" --referenceMask="MASK/$reference_mask_out" --vf="$vf_dir/vf_out_${ref}_${phase}.mhd" $coeff_out_ini --coeff="$coeff_dir/coeff_out_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log + $CLITK/clitkBLUTDIR --reference="MASK/$reference_out" --target="MASK/$target_out" --output="MASK/reg_$target_out" --referenceMask="MASK/$reference_mask_out" --vf="$vf_dir/vf_out_${ref}_${phase}.mhd" --coeff="$coeff_dir/coeff_out_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log + coeff_out_ini="--initCoeff=$coeff_dir/coeff_out_${ref}_${phase}.mhd" + ################################## + $CLITK/clitkCombineImage -i $vf_dir/vf_in_${ref}_${phase}.mhd -j $vf_dir/vf_out_${ref}_${phase}.mhd -m MASK/mm_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd + $CLITK/clitkZeroVF -i $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_${ref}_${ref}.mhd + $CLITK/clitkCombineImage -i $vf_dir/vf_${ref}_${phase}.mhd -j $vf_dir/vf_${ref}_${ref}.mhd -m MASK/patient_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd + remove_files 4 +} + +compute_DEMONSDIR() +{ + ########## register in ########## + for reg_in in $reg_in_list + do + if [ ! -z `echo $reg_in | grep "_$phase"` ] + then + target_in=$reg_in + fi + done + echo "Computing DEMONSDIR $reference_in -> $target_in ..." + $CLITK/clitkDemonsDeformableRegistration --reference="MASK/$reference_in" --target="MASK/$target_in" --output="MASK/reg_$target_in" --vf="$vf_dir/vf_in_${ref}_${phase}.mhd" $vf_in_ini $registration_parameters_DEMONSDIR #&>> LOG/registration_${ref}_${phase}.log + vf_in_ini="--init=$vf_dir/vf_in_${ref}_${phase}.mhd" + ########## register out ########## + for reg_out in $reg_out_list + do + if [ ! -z `echo $reg_out | grep "_$phase"` ] + then + target_out=$reg_out + fi + done + echo "Computing DEMONSDIR $reference_out -> $target_out ..." + $CLITK/clitkDemonsDeformableRegistration --reference="MASK/$reference_out" --target="MASK/$target_out" --output="MASK/reg_$target_out" --vf="$vf_dir/vf_out_${ref}_${phase}.mhd" $vf_out_ini $registration_parameters_DEMONSDIR #&>> LOG/registration_${ref}_${phase}.log + vf_out_ini="--init=$vf_dir/vf_out_${ref}_${phase}.mhd" + ################################## + $CLITK/clitkCombineImage -i $vf_dir/vf_in_${ref}_${phase}.mhd -j $vf_dir/vf_out_${ref}_${phase}.mhd -m MASK/mm_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd + $CLITK/clitkZeroVF -i $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_${ref}_${ref}.mhd + $CLITK/clitkCombineImage -i $vf_dir/vf_${ref}_${phase}.mhd -j $vf_dir/vf_${ref}_${ref}.mhd -m MASK/patient_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd + remove_files 4 +} + +compute_ELASTIX() +{ + ########## register in ########## + for reg_in in $reg_in_list + do + if [ ! -z `echo $reg_in | grep "_$phase"` ] + then + target_in=$reg_in + fi + done + echo "Computing ELASTIX $reference_in -> $target_in ..." + exec_dir=`which elastix` + exec_dir=`dirname $exec_dir` + cat $exec_dir/params_BSpline.txt | sed -e "s++500+" \ + -e "s+++" \ + -e "s++25+" \ + -e "s++3+" \ + -e "s++2000+" \ + -e "s++Random+" \ + -e "s++32+" > params_BSpline.txt + elastix -f "MASK/$reference_in" -m "MASK/$target_in" -fMask "MASK/$reference_mask_in" -out $vf_dir -p params_BSpline.txt > /dev/null + transformix -tp $vf_dir/TransformParameters.0.txt -out $vf_dir -def all > /dev/null + mv $vf_dir/deformationField.mhd $vf_dir/vf_in_${ref}_${phase}.mhd + mv $vf_dir/deformationField.raw $vf_dir/vf_in_${ref}_${phase}.raw + sed -i "s:deformationField:vf_in_${ref}_${phase}:" $vf_dir/vf_in_${ref}_${phase}.mhd + mv $vf_dir/result.0.mhd MASK/reg_$target_in + targetraw=`echo reg_$target_in | sed 's:mhd:raw:'` + sed -i "s:result.0.mhd:$targetraw" MASK/reg_$target_in + mv $vf_dir/result.0.raw MASK/$targetraw + remove_files 8 + + ########## register out ########## + for reg_out in $reg_out_list + do + if [ ! -z `echo $reg_out | grep "_$phase"` ] + then + target_out=$reg_out + fi + done + echo "Computing ELASTIX $reference_out -> $target_out ..." + elastix -f "MASK/$reference_out" -m "MASK/$target_out" -fMask "MASK/$reference_mask_out" -out $vf_dir -p params_BSpline.txt > /dev/null + transformix -tp $vf_dir/TransformParameters.0.txt -out $vf_dir -def all > /dev/null + mv $vf_dir/deformationField.mhd $vf_dir/vf_out_${ref}_${phase}.mhd + mv $vf_dir/deformationField.raw $vf_dir/vf_out_${ref}_${phase}.raw + sed -i "s:deformationField:vf_out_${ref}_${phase}:" $vf_dir/vf_out_${ref}_${phase}.mhd + mv $vf_dir/result.0.mhd MASK/reg_$target_out + targetraw=`echo reg_$target_out | sed 's:mhd:raw:'` + sed -i "s:result.0.mhd:$targetraw" MASK/reg_$target_out + mv $vf_dir/result.0.raw MASK/$targetraw + remove_files 8 + + ################################## + $CLITK/clitkCombineImage -i $vf_dir/vf_in_${ref}_${phase}.mhd -j $vf_dir/vf_out_${ref}_${phase}.mhd -m MASK/mm_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd + $CLITK/clitkZeroVF -i $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_${ref}_${ref}.mhd + $CLITK/clitkCombineImage -i $vf_dir/vf_${ref}_${phase}.mhd -j $vf_dir/vf_${ref}_${ref}.mhd -m MASK/patient_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd + remove_files 4 +} + +registration() +{ + echo + echo "----------- Registration ------------" + start=`date` + echo "start: $start" + echo + + rm -f "LOG/registration*.log" + + # wait any unfinished threads + check_threads 1 + + for reg_in in $reg_in_list + do + if [ ! -z `echo $reg_in | grep "$ref"` ] + then + reference_in=$reg_in + fi + done + for reg_out in $reg_out_list + do + if [ ! -z `echo $reg_out | grep "$ref"` ] + then + reference_out=$reg_out + fi + done + for regmask_in in $regmask_in_list + do + if [ ! -z `echo $regmask_in | grep "$ref"` ] + then + reference_mask_in=$regmask_in + fi + done + for regmask_out in $regmask_out_list + do + if [ ! -z `echo $regmask_out | grep "$ref"` ] + then + reference_mask_out=$regmask_out + fi + done + + registration_parameters_BLUTDIR="--spacing=32,32,32 --interp=2 --metric=11 --bins=25 --samples=1 --levels=3 --verbose " #--coeffEveryN 5" + registration_parameters_DEMONSDIR="--demons=3 --levels=1" + registration_parameters_ELASTIX="--demons=3 --levels=1" + + coeff_in_ini="" + coeff_out_ini="" + vf_in_ini="" + vf_out_ini="" + + for phase in $list_phases + do + for img in $phase_list + do + if [ ! -z `echo $img | grep "$phase" | grep -v "[0-9]$phase"` ] + then + image_name=`echo $img | sed 's/raw/mhd/'` + fi + done + if [ $method = 1 ] + then + compute_BLUTDIR + elif [ $method = 2 ] + then + compute_DEMONSDIR + elif [ $method = 3 ] + then + compute_ELASTIX + fi + done + remove_files 5 + + echo + echo "-------- Registration done ! --------" + end=`date` + echo "start: $start" + echo "end: $end" + echo +} + +calculate_vf_MIDP_REF() +{ + echo "Calculating vf_REF_MIDP.mhd..." + remove_files 6 + create_mhd_4D.sh $vf_dir #"vf_4D.mhd" + $CLITK/clitkAverageTemporalDimension -i $vf_dir/_4D.mhd -o $vf_dir/vf_${ref}_MIDP.mhd + $CLITK/clitkInvertVF -i $vf_dir/vf_${ref}_MIDP.mhd -o $vf_dir/vf_MIDP_${ref}.mhd +} + +calculate_CT_MIDP_REF() +{ + reference=`ls *.mhd | grep $ref #| grep -v "[0-9]$ref.mhd"` + echo "Calculating CT_MIDP_REF.mhd '$reference'..." + $CLITK/clitkWarpImage -i $reference -o CT_MIDP_REF.mhd --vf=$vf_dir/vf_MIDP_${ref}.mhd -s 1 +} + +calculate_CT_MIDP_PHASE() +{ + echo "Calculating CT_MIDP_${phase}.mhd..." + $CLITK/clitkComposeVF -i $vf_dir/vf_MIDP_${ref}.mhd -j $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_MIDP_${phase}.mhd + phase_img=`ls *.mhd | grep "${phase}" # | grep -v "[0-9]$ref.mhd"` + $CLITK/clitkWarpImage -i $phase_img -o MIDP/CT_MIDP_${phase}.mhd --vf=$vf_dir/vf_MIDP_${phase}.mhd -s 1 + $CLITK/clitkImageConvert -i MIDP/CT_MIDP_${phase}.mhd -o MIDP/CT_MIDP_${phase}.mhd -t float + remove_files 7 +} + +prepare_MIDP_images() +{ + echo "Preparing MIDP images..." + cp CT_MIDP_REF.mhd MIDP/CT_MIDP_${ref}.mhd + cp CT_MIDP_REF.raw MIDP/CT_MIDP_${ref}.raw + cat MIDP/CT_MIDP_${ref}.mhd | sed "s/ElementDataFile = .*/ElementDataFile = CT\_MIDP\_${ref}\.raw/" > MIDP/CT_MIDP_${ref}_tmp.mhd + rm MIDP/CT_MIDP_${ref}.mhd + mv MIDP/CT_MIDP_${ref}_tmp.mhd MIDP/CT_MIDP_${ref}.mhd + $CLITK/clitkImageConvert -i MIDP/CT_MIDP_${ref}.mhd -o MIDP/CT_MIDP_${ref}.mhd -t float + create_mhd_4D.sh MIDP #"CT_MIDP_4D.mhd" +} + +calculate_CT_MIDP_MOY() +{ + echo "Calculating CT_MIDP_MOY.mhd..." + $CLITK/clitkAverageTemporalDimension -i MIDP/_4D.mhd -o CT_MIDP_MOY.mhd +} + +calculate_CT_MIDP_MED() +{ + echo "Calculating CT_MIDP_MED.mhd..." + $CLITK/clitkMedianTemporalDimension -i MIDP/_4D.mhd -o CT_MIDP_MED.mhd +} + +calculate_CT_MIDP_MIP() +{ + echo "Calculating CT_MIDP_MIP.mhd..." + $CLITK/clitkMIP -i MIDP/_4D.mhd -o CT_MIDP_MIP.mhd -d 3 +} + +mid_position() +{ + echo + echo "----------- Mid-position ------------" + start=`date` + echo "start: $start" + echo + + mkdir -p "MIDP" + + calculate_vf_MIDP_REF + calculate_CT_MIDP_REF + for phase in $list_phases + do + check_threads $MAX_THREADS + calculate_CT_MIDP_PHASE & + done + wait + prepare_MIDP_images + calculate_CT_MIDP_MED & + calculate_CT_MIDP_MIP & + calculate_CT_MIDP_MOY & + wait + + echo + echo "-------- Mid-position done ! --------" + end=`date` + echo "start: $start" + echo "end: $end" + echo +} + +################# +# main # +################# + +if [ $# -lt 1 ] +then + echo "Usage: create_midP.sh CT_4D.mhd ref_phase computation_spacing(mm) method(1:BSPLINE, 2:DEMONS)" + exit 1 +fi +CLITK=~/creatis/clitk3/build/bin +CT_4D_path=$1 +CT_4D=`basename $CT_4D_path` +work_dir=`dirname $CT_4D_path` +cd $work_dir +ref=$2 +spacing=$3 +method=$4 + +vf_dir="VF" +coeff_dir="$vf_dir/coeff" + +mkdir -p $vf_dir +mkdir -p $coeff_dir + +echo +echo "--------------- START ---------------" +begining=`date` +echo "start: $begining" +echo + +mkdir -p "LOG" +phase_list=`grep ".raw" $CT_4D` +echo "phases -> " $phase_list +nb_phases=`grep ".raw" $CT_4D | wc -l` +gt_ref="" +lt_ref="" + +phase_files=( `cat $CT_4D | grep ".raw" | sed 's:.raw:.mhd:'` ) +echo "Phase files are ${phase_files[@]}" + +phase_nbs=( `echo ${phase_files[@]} | grep -o '[[:alpha:][:punct:]][0-9]\{1,2\}[[:punct:]]' | grep -o '[0-9]\{1,2\}'` ) +#phase_nbs=( `echo ${phase_files[@]} | grep -o '[0-9]\{1,2\}'` ) +echo "Phase numbers are ${phase_nbs[@]}" + + +for ph in $phase_list +do + #ph_nb=`echo $ph | grep -o "[0-9][0-9]*\.raw" | sed -e 's/\.raw//'` + ph_nb=`echo $ph | grep -o "[0-9][0-9]"` + if [ $ph_nb -gt $ref ] + then + gt_ref="$gt_ref $ph_nb" + elif [ $ph_nb -lt $ref ] + then + lt_ref="$lt_ref $ph_nb" + fi +done +list_phases="$gt_ref $lt_ref" +echo list_phases $list_phases + +motion_mask +registration +mid_position + +echo +echo "---------------- END ----------------" +terminating=`date` +echo "start: $begining" +echo "end: $terminating" +echo diff --git a/scripts/create_midP_masks-2.0.sh b/scripts/create_midP_masks-2.0.sh new file mode 100755 index 0000000..6023df5 --- /dev/null +++ b/scripts/create_midP_masks-2.0.sh @@ -0,0 +1,258 @@ +#! /bin/bash -x + +############################################################################### +# +# FILE: create_midP-2.0.sh +# AUTHOR: Rômulo Pinho 05/08/2011 +# +# Version 2.0 of the create_midP_masks.sh script. The most relevant changes are: +# * creation of bands around input and output image regions to try to improve +# the registration along lung boundaries (naturally, it depends on the quality +# of motion mask generation). +# * some steps are now in different modules, to facilitate re-use (see "includes" section). +# * minor modifications on output file names. +# * attempt to simplify the code a bit. +# +############################################################################### + +source `dirname $0`/common.sh + +extract_patient() +{ + echo "$phase_file -> Extracting patient..." + clitkExtractPatient -i $phase_file -o $mask_dir_tmp/patient_mask_$phase_nb.mhd --noAutoCrop -a $afdb_file $ExtractPatientExtra + clitkSetBackground -i $phase_file -o $mask_dir_tmp/patient_$phase_nb.mhd --mask $mask_dir_tmp/patient_mask_$phase_nb.mhd --outsideValue -1000 +} + +extract_bones() +{ + if [ x = x$ExtractBonesLower1 ]; then + ExtractBonesLower1=120 + fi + if [ x = x$ExtractBonesLower2 ]; then + ExtractBonesLower2=80 + fi + echo "$phase_file -> Extracting bones..." + clitkImageConvert -i $phase_file -o $mask_dir_tmp/float_$phase_nb.mhd -t float + 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 +} + +extract_lungs() +{ + echo "$phase_file -> Extracting lungs..." + clitkExtractLung -i $phase_file -o $mask_dir_tmp/lungs_$phase_nb.mhd -a $afdb_file --noAutoCrop +} + +resample() +{ + echo "$phase_file -> Resampling..." + clitkResampleImage -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/patient_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo + + 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 +} + +compute_motion_mask() +{ + if [ x = x$MotionMaskOffsetDetect ]; then + MotionMaskOffsetDetect="0,-5,0" + fi + if [ x = x$FillingLevel ]; then + FillingLevel=94 + fi + + 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 0,-5,0 --pad --writeFeature=$mask_dir_tmp/feature_$phase_nb.mhd $MotionMaskExtra + #--monitor=$mask_dir_tmp/monitor_$phase_nb.mhd +} + +create_banded_mask() +{ + input=$1 + input_mask=$2 + output=$3 + output_mask=$4 + radius=$5 + + input_dir=`dirname $input` + input_base=`basename $input` + + # first band + clitkMorphoMath -i $input_mask -o $input_dir/extra1_$input_base --type 1 --radius $radius + clitkImageArithm -i $input_dir/extra1_$input_base -j $input_mask -o $input_dir/band1_$input_base -t 7 + clitkBinarizeImage -i $input_dir/band1_$input_base -o $input_dir/band1_$input_base -l 1 -u 1 --fg 100 --mode both + clitkImageConvert -i $input_dir/band1_$input_base -o $input_dir/short_band1_$input_base -t short + + # second band + clitkMorphoMath -i $input_dir/extra1_$input_base -o $input_dir/extra2_$input_base --type 1 --radius $radius + clitkImageArithm -i $input_dir/extra2_$input_base -j $input_dir/extra1_$input_base -o $input_dir/band2_$input_base -t 7 + clitkBinarizeImage -i $input_dir/band2_$input_base -o $input_dir/band2_$input_base -l 1 -u 1 --fg 200 --mode both + clitkImageConvert -i $input_dir/band2_$input_base -o $input_dir/short_band2_$input_base -t short + + # combine bands with masks + clitkImageArithm -i $input_mask -j $input_dir/band1_$input_base -o $output_mask -t 0 + clitkImageArithm -i $output_mask -j $input_dir/band2_$input_base -o $output_mask -t 0 + # combine bands with image + clitkCombineImage -i $input_dir/short_band1_$input_base -j $input -m $input_dir/band1_$input_base -o $output + clitkCombineImage -i $input_dir/short_band2_$input_base -j $output -m $input_dir/band2_$input_base -o $output + + # clean-up + rm `echo $input_dir/extra?_$input_base | sed 's:.mhd:.*:g'` + rm `echo $input_dir/band?_$input_base | sed 's:.mhd:.*:g'` + rm `echo $input_dir/short_band?_$input_base | sed 's:.mhd:.*:g'` +} + +create_registration_masks() +{ + # extract inside and outside lung regions from the patient image, + # using the motion mask computed previously + echo "$phase_file -> Setting Background..." + 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 + 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 + + # the registration masks for inside (and outside) region correspond + # to the motion mask (and its complement) plus extra grey value bands, + # obtained with morphological dilations. + # + echo "$phase_file -> Creating registration masks..." + # inside + 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 + # outside + clitkExtractPatient -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/mm_outside_$phase_nb.mhd --noAutoCrop + 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 +} + +mm_preprocessing() +{ + extract_patient + # extract_bones + extract_lungs + # remove_tmp_masks 1 + resample +} + +mm_postprocessing() +{ + # remove_tmp_masks 2 + # remove_tmp_masks 3 + create_registration_masks +} + +motion_mask() +{ + #set cmd line variables + mhd4d=$1 + resample_spacing=$2 + resample_algo=$3 + + # import variables specific to each patient + source variables + + dir=`dirname $1` + cd $dir + + #set other global variables + mask_dir="MASK-${resample_spacing}mm-$resample_algo" + mask_dir_tmp="tmp.$mask_dir" + extract_4d_phases $mhd4d + + echo + echo "------------ Motion mask from create_midP_masks.sh ------------" + start=`date` + echo "start: $start" + echo + + # the motion masks are first created in a tmp directory. this directory is + # later going to be renamed to the final motion mask directory. concurrent + # executions trying to create the same set of masks will be blocked until + # the first execution finishes. naturally, these other executions will not + # recreate the masks. so first we try to create the tmp directory. + # if the creation fails, it means that another execution is + # already creating the masks, so this execution will be blocked. the + # execution is unblocked only when the creation of masks is finished and + # the mask directory is renamed. + # + # ATTENTION: RP - 08/02/2011 + # robustness issue: tmp directory may exist but may be empty or + # incomplete. the solution is to check per file, but I'll leave it like + # this for the moment. + do_mm=0 + if [ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]; then + mkdir $mask_dir_tmp 2> /dev/null + return_mkdir=$? + if [ $return_mkdir == 0 ]; then + do_mm=1 + else + while [[ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]]; do + echo "waiting creation of motion masks..." + sleep 2 + done + echo "finished waiting" + fi + fi + +# do_mm=1 +# mask_dir_tmp=$mask_dir + if [ $do_mm == 1 ]; then + mask_log_dir=$mask_dir_tmp/LOG + mkdir -p $mask_log_dir + + # multi-threaded pre-processing for motion mask calcs + for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do + phase_nb=${phase_nbs[$i]} + phase_file=${phase_files[$i]} + afdb_file=`echo $phase_file | sed 's/mhd/afdb/'` + + check_threads $MAX_THREADS + mm_preprocessing & + done + + # single-threaded motion mask calc + for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do + phase_nb=${phase_nbs[$i]} + phase_file=${phase_files[$i]} + + check_threads 1 + echo "$phase_file -> Computing motion mask..." + compute_motion_mask > $mask_log_dir/motion_mask_$phase_file.log + done + + # multi-threaded post-processing of motion mask calcs + for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do + phase_nb=${phase_nbs[$i]} + phase_file=${phase_files[$i]} + + check_threads $MAX_THREADS + mm_postprocessing & + done + + # rename tmp mask directory after mask creation + check_threads 1 + mv -f $mask_dir_tmp $mask_dir + fi + + echo + echo "-------- Motion mask done ! ---------" + end=`date` + echo "start: $start" + echo "end: $end" + echo +} + + +################# +# main # +################# + +if [ $# != 3 ]; then + echo "Usage: $0 CT_4D RESAMPLE_SPACING RESAMPLE_ALGORITHM" + exit -1 +fi + +# +# variables exported in this scope +# +# mask_dir: directory where all masks are kept +# + +if [ $1 != "using-as-lib" ]; then + motion_mask $1 $2 $3 +fi diff --git a/scripts/create_midP_masks.sh b/scripts/create_midP_masks.sh index 9c85177..471ce6b 100755 --- a/scripts/create_midP_masks.sh +++ b/scripts/create_midP_masks.sh @@ -1,6 +1,6 @@ #! /bin/bash -x -. common.sh +source `dirname $0`/common.sh extract_patient() { @@ -241,7 +241,7 @@ fi # # variables exported in this scope # -# mask_dir: directory where all mask are kept +# mask_dir: directory where all masks are kept # regmask_in_list: list of registration mask files (inside lungs) # regmask_out_list: list of registration mask files (outised lungs) # reg_in_list: list of registration image files (inside lungs) diff --git a/scripts/pts_to_landmarks.sh b/scripts/pts_to_landmarks.sh new file mode 100755 index 0000000..87bc9ee --- /dev/null +++ b/scripts/pts_to_landmarks.sh @@ -0,0 +1,27 @@ +#! /bin/sh + +############################################################################### +# +# FILE: pts_to_landmarks +# AUTHOR: Vivien Delmon +# +# Conversion from landmarks in the format used in clitkCalculateTRE (.pts) +# to the format used in VV (.txt). +# +############################################################################### + +if [ $# -ne 2 ]; then + echo "Usage: $0 input.pts output.txt" 1>&2 +fi + +to_append=/tmp/$RANDOM +to_prepend=/tmp/$RANDOM + +for i in $(seq 0 $((`cat $1 | wc -l` - 1))); +do + echo 0' '0 >> $to_append + echo $i >> $to_prepend +done + +echo "LANDMARKS1" > $2 +paste -d ' ' $to_prepend $1 $to_append >> $2 diff --git a/scripts/registration.sh b/scripts/registration.sh new file mode 100755 index 0000000..3979654 --- /dev/null +++ b/scripts/registration.sh @@ -0,0 +1,123 @@ +#! /bin/sh + +############################################################################### +# +# FILE: registration.sh +# AUTHOR: Rômulo Pinho 05/08/2011 +# +# Helper file with registration functions using different methods. +# Each function receives a set of parameters that overall apply to any +# registration algorithm, as follows: +# +# reference=$1 : reference (fixed) image +# target=$2 : target (moving) image +# mask_ref=$3 : mask for the reference image +# mask_targ=$4 : mask for the moving image +# vf=$5 : output vector field representing the registration +# result=$6 : result image after applying the vector field +# nb_iter=$7 : maximum number of iterations +# nb_samples=$8 : number of image samples used in the metric calulcation +# sampling_algo=$9 : algorithm used in the selection of image samples +# hist_bins=${10} : number of histogram bins used in the metric calculation +# nb_levels=${11} : number of image resolutions +# spacing=${12} : spacing of the b-spline grid of the fines resolution +# metric=${13} : metric algorithm +# optimizer=${14} : optimizer +# interpolator=${15} : image interpolator +# log=${16} : log file +# +# New registration functions may be added to this file at any moment, +# respecting the interface defined above. +# +############################################################################### + + +################# BLUTDIR ##################### +registration_blutdir() +{ + reference=$1 + target=$2 + mask_ref=$3 + mask_targ=$4 + vf=$5 + result=$6 + nb_iter=$7 + nb_samples=$8 + sampling_algo=$9 + hist_bins=${10} + nb_levels=${11} + spacing=${12} + metric=${13} + optimizer=${14} + interpolator=${15} + log=${16} + + echo "Computing BLUTDIR $reference -> $target ..." + blutdir_params="--levels $nb_levels --metric $metric --optimizer $optimizer --samples $nb_samples --spacing $spacing,$spacing,$spacing --bins $hist_bins --maxIt $nb_iter --interp $interpolator --verbose" + cmd="clitkBLUTDIR -r $reference -t $target -m $mask_ref --targetMask $mask_targ --vf $vf -o $result $blutdir_params" + $cmd > $log +} + +################# ELASTIX ##################### +registration_elastix() +{ + reference=$1 + target=$2 + mask_ref=$3 + mask_targ=$4 + vf=$5 + result=$6 + nb_iter=$7 + nb_samples=$8 + sampling_algo=$9 + hist_bins=${10} + nb_levels=${11} + spacing=${12} + metric=${13} + optimizer=${14} + interpolator=${15} + + ########## register in ########## + for reg_in in $reg_in_list + do + if [ ! -z `echo $reg_in | grep "_$phase"` ] + then + target_in=$reg_in + fi + done + echo "Computing ELASTIX $reference -> $target ..." + exec_dir=`which elastix` + exec_dir=`dirname $exec_dir` + cat $exec_dir/params_BSpline.txt | sed -e "s++$nb_iter+" \ + -e "s+++" \ + -e "s++$hist_bins+" \ + -e "s++$nb_levels+" \ + -e "s++$nb_samples+" \ + -e "s++$sampling_algo+" \ + -e "s++$spacing+" > params_BSpline.txt + + vf_dir=`dirname $vf` + vf_base=`basename $vf .mhd` + result_dir=`dirname $result` + result_base=`basename $result .mhd` + + # image registration + cmd="elastix -f $reference -m $target -fMask $mask_ref -mMask $mask_targ -out $result_dir -p params_BSpline.txt" + $cmd > /dev/null + + # generate vector field + cmd="transformix -tp $result_dir/TransformParameters.0.txt -out $vf_dir -def all" + $cmd > /dev/null + + # post-processing + mv $vf_dir/deformationField.mhd $vf + mv $vf_dir/deformationField.raw `echo $vf | sed 's/mhd/raw/'` + sed -i "s+deformationField+$vf_base+" $vf + + mv $result_dir/result.0.mhd $result + mv $result_dir/result.0.raw `echo $result | sed 's/mhd/raw/'` + sed -i "s+result.0+$result_base+" $result + + mv $result_dir/elasitx.log $log + mv $result_dir/TransformParameters.0.txt $result_dir/${result_base}_TransformParameters.0.txt +} \ No newline at end of file -- 2.45.1