]> Creatis software - clitk.git/commitdiff
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
authorSimon Rit <simon.rit@creatis.insa-lyon.fr>
Wed, 4 Sep 2013 12:31:41 +0000 (14:31 +0200)
committerSimon Rit <simon.rit@creatis.insa-lyon.fr>
Wed, 4 Sep 2013 12:31:41 +0000 (14:31 +0200)
40 files changed:
cluster_tools/CMakeLists.txt [new file with mode: 0644]
cluster_tools/gate_make_merge_release.sh [new file with mode: 0755]
cluster_tools/gate_power_merge.sh
common/CMakeLists.txt
common/clitkCommon.h
common/clitkElastix.h [new file with mode: 0644]
common/clitkMatrix.cxx [new file with mode: 0644]
common/clitkMatrix.h [new file with mode: 0644]
common/clitkTransformUtilities.h
common/vvImage.h
common/vvImageReader.cxx
itk/clitkLabelImageOverlapMeasureFilter.h
itk/clitkLabelImageOverlapMeasureFilter.txx
itk/clitkResampleImageWithOptionsFilter.txx
itk/itkLabelOverlapMeasuresImageFilter.h [deleted file]
itk/itkLabelOverlapMeasuresImageFilter.txx [deleted file]
superbuild/CMakeLists.txt
tools/CMakeLists.txt
tools/GateMergeManager.cc [new file with mode: 0644]
tools/GateMergeManager.hh [new file with mode: 0644]
tools/clitkAffineTransformGenericFilter.h
tools/clitkAffineTransformGenericFilter.txx
tools/clitkDice.cxx [new file with mode: 0644]
tools/clitkDice.ggo [new file with mode: 0644]
tools/clitkElastixTransformToMatrix.cxx
tools/clitkImageUncertainty.cxx [new file with mode: 0644]
tools/clitkImageUncertainty.ggo [new file with mode: 0644]
tools/clitkLabelImageOverlapMeasureGenericFilter.h [new file with mode: 0644]
tools/clitkLabelImageOverlapMeasureGenericFilter.txx [new file with mode: 0644]
tools/clitkMatrixInverse.cxx [new file with mode: 0644]
tools/clitkMatrixInverse.ggo [new file with mode: 0644]
tools/clitkMatrixToElastixTransform.cxx [new file with mode: 0644]
tools/clitkMatrixToElastixTransform.ggo [new file with mode: 0644]
tools/clitkMergeAsciiDoseActor.cxx [new file with mode: 0644]
tools/clitkMergeAsciiDoseActor.ggo [new file with mode: 0644]
tools/clitkMergeRootFiles.cxx [new file with mode: 0644]
tools/clitkMergeRootFiles.ggo [new file with mode: 0644]
vv/vvMainWindow.cxx
vv/vvMainWindow.h
vv/vvToolRigidReg.cxx

diff --git a/cluster_tools/CMakeLists.txt b/cluster_tools/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ed8288b
--- /dev/null
@@ -0,0 +1,15 @@
+#=========================================================
+# Install scripts when running make install
+SET(SCRIPTS
+  gate_job_cluster.job
+  gate_make_merge_release.sh
+  gate_make_release.sh
+  gate_power_merge.sh
+  gate_run_submit_cluster.sh
+  gate_upload_release.sh
+  mergeDosePerEnergyFile.sh
+  mergeStatFile.py
+  mergeStatFile.sh
+)
+
+INSTALL (FILES ${SCRIPTS} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
diff --git a/cluster_tools/gate_make_merge_release.sh b/cluster_tools/gate_make_merge_release.sh
new file mode 100755 (executable)
index 0000000..e506728
--- /dev/null
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+set -u
+set -e
+
+function error {
+echo "ERROR: $1"
+echo "$(basename $0)"
+exit 1
+}
+
+function get_deps {
+targetbinary=${1}
+targetdir=${2}
+test -d ${targetdir} || error "${targetdir} isn't a directory"
+ldd ${targetbinary} | while read library; do
+       libfile="$(echo ${library} | awk -F' ' '/=> \// {print $3}')"
+       test $libfile || continue # didn't macht regex
+       test -f "${targetdir}/$(basename ${libfile})" && continue # already exists
+       cp "${libfile}" "${targetdir}"
+       get_deps "${libfile}" "${targetdir}"
+done
+}
+
+function package_target {
+targetname="${1}"
+which "${targetname}" > /dev/null || error "cant locate ${targetname}"
+targetbin="$(which ${targetname})"
+echo "${targetname} executable is ${targetbin}"
+
+echo "Getting libraries"
+targetdir="$(mktemp -d)"
+get_deps "${targetbin}" "${targetdir}"
+
+echo "Removing unused libraries"
+rm -f ${targetdir}/libdl.so*
+rm -f ${targetdir}/libm.so*
+rm -f ${targetdir}/libstdc++.so*
+rm -f ${targetdir}/libgcc_s.so*
+rm -f ${targetdir}/libpthread.so*
+rm -f ${targetdir}/libc.so*
+
+echo "Copying binary"
+cp "${targetbin}" .
+for filename in $(find ${targetdir} -name '*.so*'); do cp ${filename} . ; done
+
+echo "Cleaning up"
+rm -r "${targetdir}"
+}
+
+filenames=("clitkImageArithm" "clitkMergeRootFiles" "clitkMergeAsciiDoseActor" "clitkImageUncertainty" "mergeStatFile.sh" "gate_power_merge.sh")
+
+for input in "${filenames[@]}"; do
+       package_target "${input}" || error "error while packaging ${input}"
+done
+
+echo "Making release"
+tar -czvf merge_release.tar.gz ** \
+        || usage "can't create release zip"
+
+
+
index 4b5f18486ceb8148a1d68426366999e1a533a5f3..e35a683fb2bcf3694eed7f10519995efe4333d58 100755 (executable)
@@ -1,41 +1,41 @@
 #!/usr/bin/env bash
 
-set -u 
+set -u
 
 function error {
-echo "ERROR: $1"
-exit 1
+    echo "ERROR: $1"
+    exit 1
 }
 
 warning_count=0
 function warning {
-let "warning_count++"
-echo "MERGE_WARNING: $1"
+    let "warning_count++"
+    echo "MERGE_WARNING: $1"
 }
 
 function start_bar {
-count_max="${1:?"provide count max"}"
+    count_max="${1:?"provide count max"}"
 }
 
 function update_bar {
-local count="${1:?"provide count"}"
-local message="${2:?"provide message"}"
-local percent=$(echo "100*${count}/${count_max}" | bc)
-#printf "[%03d/%03d] %3d%% %-80.80s\r" ${count} ${count_max} ${percent} "${message}"
-printf "[%03d/%03d] %3d%% %-80.80s\n" ${count} ${count_max} ${percent} "${message}"
+    local count="${1:?"provide count"}"
+    local message="${2:?"provide message"}"
+    local percent=$(echo "100*${count}/${count_max}" | bc)
+    #printf "[%03d/%03d] %3d%% %-80.80s\r" ${count} ${count_max} ${percent} "${message}"
+    printf "[%03d/%03d] %3d%% %-80.80s\n" ${count} ${count_max} ${percent} "${message}"
 }
 
 function end_bar {
-unset count_max
-#echo -ne '\n'
+    unset count_max
+    #echo -ne '\n'
 }
 
 function check_interfile {
-local input_interfile="${1:?"provide input interfile"}"
+    local input_interfile="${1:?"provide input interfile"}"
 
-grep -qs '!INTERFILE :=' "${input_interfile}" || return 1
+    grep -qs '!INTERFILE :=' "${input_interfile}" || return 1
 
-local header_byte_size=$(awk -F' ' '
+    local header_byte_size=$(awk -F' ' '
 BEGIN { zsize = 0; }
 /matrix size/ && $3 == "[1]" { xsize = $5; }
 /matrix size/ && $3 == "[2]" { ysize = $5; }
@@ -43,19 +43,19 @@ BEGIN { zsize = 0; }
 /number of bytes per pixel/ { byte_per_pixel = $7; }
 END { print xsize * ysize * zsize * byte_per_pixel; }' "${input_interfile}")
 
-local raw_interfile="$(dirname "${input_interfile}")/$(awk -F' := ' '/name of data file/ { print $2; }' "${input_interfile}")"
+    local raw_interfile="$(dirname "${input_interfile}")/$(awk -F' := ' '/name of data file/ { print $2; }' "${input_interfile}")"
 
-test -f "${raw_interfile}" || return 1
-test $(stat -c%s "${raw_interfile}") -eq ${header_byte_size} || return 1
+    test -f "${raw_interfile}" || return 1
+    test $(stat -c%s "${raw_interfile}") -eq ${header_byte_size} || return 1
 }
 
 function write_mhd_header {
-local input_interfile="${1:?"provide input interfile"}"
-local output_mhd="$(dirname "${input_interfile}")/$(basename "${input_interfile}" ".hdr").mhd"
+    local input_interfile="${1:?"provide input interfile"}"
+    local output_mhd="$(dirname "${input_interfile}")/$(basename "${input_interfile}" ".hdr").mhd"
 
-check_interfile "${input_interfile}" || error "${input_interfile} isn't an interfile image"
+    check_interfile "${input_interfile}" || error "${input_interfile} isn't an interfile image"
 
-local header_start='ObjectType = Image
+    local header_start='ObjectType = Image
 NDims = 3
 AcquisitionDate = none
 BinaryData = True
@@ -67,21 +67,21 @@ CenterOfRotation = 0 0 0
 DistanceUnits = mm
 AnatomicalOrientation = RIP'
 
-echo "${header_start}" > "${output_mhd}"
+    echo "${header_start}" > "${output_mhd}"
 
-awk -F' ' '
+    awk -F' ' '
 /scaling factor/ && $4 == "[1]" { xspacing = $6; }
 /scaling factor/ && $4 == "[2]" { yspacing = $6; }
 END { print "ElementSpacing = " xspacing " " yspacing " 1"; }' "${input_interfile}" >> "${output_mhd}"
 
-awk -F' ' '
+    awk -F' ' '
 BEGIN { zsize = 0; }
 /matrix size/ && $3 == "[1]" { xsize = $5; }
 /matrix size/ && $3 == "[2]" { ysize = $5; }
 /number of projections/ { zsize += $5; }
 END { print "DimSize = " xsize " " ysize " " zsize; }' "${input_interfile}" >> "${output_mhd}"
 
-awk -F' := ' '
+    awk -F' := ' '
 /number format/ { format = $2; }
 /number of bytes per pixel/ { byte_per_pixel = $2 }
 END {
@@ -98,7 +98,7 @@ if (format == "float" && byte_per_pixel == 4) { print "ElementType = MET_DOUBLE"
 print "ElementType = MET_INT";
 }' "${input_interfile}" >> "${output_mhd}"
 
-awk -F' := ' '
+    awk -F' := ' '
 /name of data file/ { print "ElementDataFile = " $2; }' "${input_interfile}" >> "${output_mhd}"
 }
 
@@ -106,200 +106,200 @@ rootMerger="clitkMergeRootFiles"
 test -x "./clitkMergeRootFiles" && rootMerger="./clitkMergeRootFiles"
 
 function merge_root {
-local merged="$1"
-shift
-echo "  ${indent}entering root merger"
-echo "  ${indent}merger is ${rootMerger}"
-echo "  ${indent}creating ${merged}"
-#echo "######## $#"
-#echo "######## $*"
-
-if test $# -eq 1
-then
-    echo "  ${indent}just one partial file => just copy it"
-    cp "$1" "${merged}"
-    return
-fi
-
-local count=0
-local arguments=" -o ${merged}"
-while test $# -gt 0
-do
-    local partial="$1"
+    local merged="$1"
     shift
-    let count++
-    local arguments=" -i ${partial} ${arguments}"
-done
-${rootMerger} ${arguments} > /dev/null || error "error while calling ${rootMerger}"
-echo "  ${indent}merged ${count} files"
+    echo "  ${indent}entering root merger"
+    echo "  ${indent}merger is ${rootMerger}"
+    echo "  ${indent}creating ${merged}"
+    #echo "######## $#"
+    #echo "######## $*"
+
+    if test $# -eq 1
+    then
+        echo "  ${indent}just one partial file => just copy it"
+        cp "$1" "${merged}"
+        return
+    fi
+
+    local count=0
+    local arguments=" -o ${merged}"
+    while test $# -gt 0
+    do
+        local partial="$1"
+        shift
+        let count++
+        local arguments=" -i ${partial} ${arguments}"
+    done
+    ${rootMerger} ${arguments} > /dev/null || error "error while calling ${rootMerger}"
+    echo "  ${indent}merged ${count} files"
 }
 
 statMerger="mergeStatFile.py"
 test -x "./mergeStatFile.sh" && statMerger="./mergeStatFile.sh"
 
 function merge_stat {
-local merged="$1"
-shift
-echo "  ${indent}entering stat merger"
-echo "  ${indent}merger is ${statMerger}"
-echo "  ${indent}creating ${merged}"
-local count=0
-start_bar $#
-while test $# -gt 0
-do
-    local partial="$1"
+    local merged="$1"
     shift
-    let count++
-
-    if test ! -f "${merged}"
-    then
-        update_bar ${count} "copying first partial result ${partial}"
-        cp "${partial}" "${merged}"
-        continue
-    fi
+    echo "  ${indent}entering stat merger"
+    echo "  ${indent}merger is ${statMerger}"
+    echo "  ${indent}creating ${merged}"
+    local count=0
+    start_bar $#
+    while test $# -gt 0
+    do
+        local partial="$1"
+        shift
+        let count++
+
+        if test ! -f "${merged}"
+        then
+            update_bar ${count} "copying first partial result ${partial}"
+            cp "${partial}" "${merged}"
+            continue
+        fi
 
-    update_bar ${count} "adding ${partial}"
-    ${statMerger} -i "${merged}" -j "${partial}" -o "${merged}" 2> /dev/null > /dev/null || warning "error while calling ${statMerger}"
-done
-end_bar
-echo "  ${indent}merged ${count} files"
+        update_bar ${count} "adding ${partial}"
+        ${statMerger} -i "${merged}" -j "${partial}" -o "${merged}" 2> /dev/null > /dev/null || warning "error while calling ${statMerger}"
+    done
+    end_bar
+    echo "  ${indent}merged ${count} files"
 }
 
 doseMerger="mergeDosePerEnegryFile.sh"
 test -x "./mergeDosePerEnergyFile.sh" && doseMerger="./mergeDosePerEnergyFile.sh"
 
 function merge_dose {
-local merged="$1"
-shift
-echo "  ${indent}entering dose merger"
-echo "  ${indent}merger is ${doseMerger}"
-echo "  ${indent}creating ${merged}"
-local count=0
-start_bar $#
-while test $# -gt 0
-do
-    local partial="$1"
+    local merged="$1"
     shift
-    let count++
-
-    if test ! -f "${merged}"
-    then
-        update_bar ${count} "copying first partial result ${partial}"
-        cp "${partial}" "${merged}"
-        continue
-    fi
+    echo "  ${indent}entering dose merger"
+    echo "  ${indent}merger is ${doseMerger}"
+    echo "  ${indent}creating ${merged}"
+    local count=0
+    start_bar $#
+    while test $# -gt 0
+    do
+        local partial="$1"
+        shift
+        let count++
+
+        if test ! -f "${merged}"
+        then
+            update_bar ${count} "copying first partial result ${partial}"
+            cp "${partial}" "${merged}"
+            continue
+        fi
 
-    update_bar ${count} "adding ${partial}"
-    ${doseMerger} -i "${merged}" -j "${partial}" -o "${merged}" 2> /dev/null > /dev/null || warning "error while calling ${doseMerger}"
-done
-end_bar
-echo "  ${indent}merged ${count} files"
+        update_bar ${count} "adding ${partial}"
+        ${doseMerger} -i "${merged}" -j "${partial}" -o "${merged}" 2> /dev/null > /dev/null || warning "error while calling ${doseMerger}"
+    done
+    end_bar
+    echo "  ${indent}merged ${count} files"
 }
 
 txtImageMerger="clitkMergeAsciiDoseActor"
 test -f "./clitkMergeAsciiDoseActor" && txtImageMerger="./clitkMergeAsciiDoseActor"
 
 function merge_txt_image {
-local merged="$1"
-shift
-echo "  ${indent}entering text image merger"
-echo "  ${indent}merger is ${txtImageMerger}"
-echo "  ${indent}creating ${merged}"
-local count=0
-start_bar $#
-while test $# -gt 0
-do
-    local partial="$1"
+    local merged="$1"
     shift
-    let count++
-
-    if test ! -f "${merged}"
-    then
-        update_bar ${count} "copying first partial result ${partial}"
-        cp "${partial}" "${merged}"
-        continue
-    fi
+    echo "  ${indent}entering text image merger"
+    echo "  ${indent}merger is ${txtImageMerger}"
+    echo "  ${indent}creating ${merged}"
+    local count=0
+    start_bar $#
+    while test $# -gt 0
+    do
+        local partial="$1"
+        shift
+        let count++
+
+        if test ! -f "${merged}"
+        then
+            update_bar ${count} "copying first partial result ${partial}"
+            cp "${partial}" "${merged}"
+            continue
+        fi
 
-    update_bar ${count} "adding ${partial}"
-    local header="$(cat "${merged}" | head -n 6)"
-    local tmp="$(mktemp)"
-    ${txtImageMerger} -i "${partial}" -j "${merged}" -o "${tmp}" 2> /dev/null > /dev/null || warning "error while calling ${txtImageMerger}"
-    echo "${header}" > "${merged}"
-    grep -v '## Merge' "${tmp}" >> "${merged}"
-    rm "${tmp}"
-done
-end_bar
-echo "  ${indent}merged ${count} files"
+        update_bar ${count} "adding ${partial}"
+        local header="$(cat "${merged}" | head -n 6)"
+        local tmp="$(mktemp)"
+        ${txtImageMerger} -i "${partial}" -j "${merged}" -o "${tmp}" 2> /dev/null > /dev/null || warning "error while calling ${txtImageMerger}"
+        echo "${header}" > "${merged}"
+        grep -v '## Merge' "${tmp}" >> "${merged}"
+        rm "${tmp}"
+    done
+    end_bar
+    echo "  ${indent}merged ${count} files"
 }
 
 hdrImageMerger="clitkImageArithm"
 test -x "./clitkImageArithm" && hdrImageMerger="./clitkImageArithm"
 
 function merge_hdr_image {
-local merged="$1"
-local merged_bin="${merged%.*}.img"
-shift
-echo "  ${indent}entering hdr image merger"
-echo "  ${indent}merger is ${hdrImageMerger}"
-echo "  ${indent}creating ${merged}"
-local count=0
-start_bar $#
-while test $# -gt 0
-do
-    local partial="$1"
-    local partial_bin="${partial%.*}.img"
+    local merged="$1"
+    local merged_bin="${merged%.*}.img"
     shift
-    let count++
-
-    if test ! -f "${merged}"
-    then
-        update_bar ${count} "copying first partial result ${partial}"
-        cp "${partial}" "${merged}"
-        cp "${partial_bin}" "${merged_bin}"
-        continue
-    fi
+    echo "  ${indent}entering hdr image merger"
+    echo "  ${indent}merger is ${hdrImageMerger}"
+    echo "  ${indent}creating ${merged}"
+    local count=0
+    start_bar $#
+    while test $# -gt 0
+    do
+        local partial="$1"
+        local partial_bin="${partial%.*}.img"
+        shift
+        let count++
+
+        if test ! -f "${merged}"
+        then
+            update_bar ${count} "copying first partial result ${partial}"
+            cp "${partial}" "${merged}"
+            cp "${partial_bin}" "${merged_bin}"
+            continue
+        fi
 
-    update_bar ${count} "adding ${partial}"
-    ${hdrImageMerger} -t 0 -i "${partial}" -j "${merged}" -o "${merged}" 2> /dev/null > /dev/null || warning "error while calling ${hdrImageMerger}"
-done
-end_bar
-echo "  ${indent}merged ${count} files"
+        update_bar ${count} "adding ${partial}"
+        ${hdrImageMerger} -t 0 -i "${partial}" -j "${merged}" -o "${merged}" 2> /dev/null > /dev/null || warning "error while calling ${hdrImageMerger}"
+    done
+    end_bar
+    echo "  ${indent}merged ${count} files"
 }
 
 mhdImageMerger="clitkImageArithm"
 test -x "./clitkImageArithm" && mhdImageMerger="./clitkImageArithm"
 
 function merge_mhd_image {
-local merged="$1"
-local merged_bin="${merged%.*}.raw"
-shift
-echo "  ${indent}entering mhd image merger"
-echo "  ${indent}merger is ${mhdImageMerger}"
-echo "  ${indent}creating ${merged}"
-local count=0
-start_bar $#
-while test $# -gt 0
-do
-    local partial="$1"
-    local partial_bin="$(dirname "${partial}")/$(awk -F' = ' '/ElementDataFile/ { print $2; }' "${partial}")"
+    local merged="$1"
+    local merged_bin="${merged%.*}.raw"
     shift
-    let count++
-
-    if test ! -f "${merged}"
-    then
-        update_bar ${count} "copying first partial result ${partial}"
-        cp "${partial}" "${merged}"
-        cp "${partial_bin}" "${merged_bin%.*}.${partial_bin##*.}"
-        continue
-    fi
+    echo "  ${indent}entering mhd image merger"
+    echo "  ${indent}merger is ${mhdImageMerger}"
+    echo "  ${indent}creating ${merged}"
+    local count=0
+    start_bar $#
+    while test $# -gt 0
+    do
+        local partial="$1"
+        local partial_bin="$(dirname "${partial}")/$(awk -F' = ' '/ElementDataFile/ { print $2; }' "${partial}")"
+        shift
+        let count++
+
+        if test ! -f "${merged}"
+        then
+            update_bar ${count} "copying first partial result ${partial}"
+            cp "${partial}" "${merged}"
+            cp "${partial_bin}" "${merged_bin%.*}.${partial_bin##*.}"
+            continue
+        fi
 
-    update_bar ${count} "adding ${partial}"
-    ${mhdImageMerger} -t 0 -i "${partial}" -j "${merged}" -o "${merged}" 2> /dev/null > /dev/null || warning "error while calling ${mhdImageMerger}"
-    mv "${merged_bin}" "${merged_bin%.*}.${partial_bin##*.}"
-    sed -i "s/$(basename "${merged_bin}")/$(basename "${merged_bin%.*}.${partial_bin##*.}")/" "${merged}"
-done
-end_bar
-echo "  ${indent}merged ${count} files"
+        update_bar ${count} "adding ${partial}"
+        ${mhdImageMerger} -t 0 -i "${partial}" -j "${merged}" -o "${merged}" 2> /dev/null > /dev/null || warning "error while calling ${mhdImageMerger}"
+        mv "${merged_bin}" "${merged_bin%.*}.${partial_bin##*.}"
+        sed -i "s/$(basename "${merged_bin}")/$(basename "${merged_bin%.*}.${partial_bin##*.}")/" "${merged}"
+    done
+    end_bar
+    echo "  ${indent}merged ${count} files"
 }
 
 function merge_dispatcher {
@@ -420,6 +420,69 @@ function merge_dispatcher {
     error "unknown file type"
 }
 
+function merge_dispatcher_uncertainty {
+    local indent="  ** "
+    local outputfile="${1:?"provide output filename"}"
+
+    local partialoutputfiles="$(find "${rundir}" -mindepth 2 -type f -name "${outputfile}")"
+    local nboutputfiles="$(echo "${partialoutputfiles}" | wc -l)"
+    if test ${nboutputdirs} -ne ${nboutputfiles}
+    then
+        warning "missing files"
+        return
+    fi
+
+    local firstpartialoutputfile="$(echo "${partialoutputfiles}" | head -n 1)"
+    local firstpartialoutputextension="${firstpartialoutputfile##*.}"
+
+    if [[ "${firstpartialoutputfile}" == *Uncertainty* ]]
+    then
+        if test "${firstpartialoutputextension}" == "mhd"
+        then
+            echo "${indent}Uncertainty file found: ${firstpartialoutputfile}"
+            ## search for sum
+            local mergedfile="${outputdir}/$(basename "${firstpartialoutputfile}")"
+            summed_merged_file=${mergedfile//-Uncertainty/}
+            if [ ! -f ${summed_merged_file} ];
+            then
+                warning "${summed_merged_file} does not exist. Error, no uncertainty computed"
+                return;
+            fi
+            echo "${indent}${summed_merged_file} found"
+            ## search for Squared
+            squared_merged_file=${mergedfile//-Uncertainty/-Squared}
+            if [ ! -f ${squared_merged_file} ];
+            then
+                warning "${squared_merged_file} does not exist. Error, no uncertainty computed"
+                return;
+            fi
+            echo "${indent}${squared_merged_file} found"
+            ## search for NumberOfEvent
+            totalEvents=0;
+            for outputfile in $(find "${rundir}" -regextype 'posix-extended' -type f -regex "${rundir}/output.*\.(hdr|mhd|root|txt)" | awk -F '/' '{ print $NF; }' | sort | uniq)
+            do
+                #echo $outputfile
+                if grep -q 'NumberOfEvent' "${outputdir}/${outputfile}"
+                then
+                    totalEvents="$(grep "NumberOfEvents" "${outputdir}/${outputfile}" | cut -d' ' -f4)"
+                    echo "${indent}Find the NumberOfEvent in $outputfile: ${totalEvents}"
+                fi
+            done
+
+            if test ${totalEvents} -gt 0
+            then
+                uncerImageMerger="clitkImageUncertainty"
+                test -x "./clitkImageUncertainty" && uncerImageMerger="./clitkImageUncertainty"
+                ${uncerImageMerger} -i ${summed_merged_file} -s ${squared_merged_file} -o ${mergedfile} -n ${totalEvents}
+            else
+                warning "${totalEvents} not positive. A at least one stat file (SimulationStatisticActor) must be provided. Error, no uncertainty computed"
+                return;
+            fi
+        fi
+    fi
+
+}
+
 echo "!!!! this is $0 v0.3k !!!!"
 
 rundir="${1?"provide run dir"}"
@@ -436,6 +499,7 @@ then
 fi
 outputdir="$(basename "${outputdir}")"
 echo "output dir is ${outputdir}"
+
 test -d "${outputdir}" && rm -r "${outputdir}"
 mkdir "${outputdir}"
 
@@ -444,10 +508,17 @@ do
     merge_dispatcher "${outputfile}"
 done
 
+echo ""
+echo "Merging done. Special case for statistical uncertainty"
+for outputfile in $(find "${outputdir}" -regextype 'posix-extended' -type f -regex "${outputdir}/output.*\.(hdr|mhd|root|txt)" | awk -F '/' '{ print $NF; }' | sort | uniq)
+do
+    merge_dispatcher_uncertainty "${outputfile}"
+done
+
 if [ -f "${rundir}/params.txt" ]
 then
-       echo "copying params file"
-       cp "${rundir}/params.txt" "${outputdir}/params.txt"
+    echo "copying params file"
+    cp "${rundir}/params.txt" "${outputdir}/params.txt"
 fi
 
 echo "these was ${warning_count} warning(s)"
index 95a1023733734e2e18037763c6fa1247a22b8426..bef0f36c799d76257671f6044a701d67479787b5 100644 (file)
@@ -39,6 +39,7 @@ SET(clitkCommon_SRC
   clitkExceptionObject.cxx
   clitkFilterBase.cxx
   clitkMemoryUsage.cxx
+  clitkMatrix.cxx
   vvImage.cxx
   vvImageReader.cxx
   vvImageWriter.cxx
index 8cd82fbe0b0bc1b20f38876368f0d6348615b1a9..2f5b26f1173b3e5e94999816031695c13cb2afc4 100644 (file)
@@ -43,6 +43,8 @@
 #  include <stdint.h>
 #endif
 
+#define VTK_EXCLUDE_STRSTREAM_HEADERS
+
 //--------------------------------------------------------------------
 namespace clitk {
 
diff --git a/common/clitkElastix.h b/common/clitkElastix.h
new file mode 100644 (file)
index 0000000..738181f
--- /dev/null
@@ -0,0 +1,167 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+#ifndef clitkElastix_h
+#define clitkElastix_h
+
+#include <itkEuler3DTransform.h>
+#include <iterator>
+
+//--------------------------------------------------------------------
+namespace clitk {
+
+//-------------------------------------------------------------------
+bool
+GetElastixValueFromTag(std::ifstream & is,
+                       std::string tag,
+                       std::string & value)
+{
+  std::string line;
+  is.seekg (0, is.beg);
+  while(std::getline(is, line))   {
+    unsigned pos = line.find(tag);
+    if (pos<line.size()) {
+      value=line.substr(pos+tag.size(),line.size()-2);// remove last ')'
+      value.erase (std::remove (value.begin(), value.end(), '"'), value.end());
+      value.erase (std::remove (value.begin(), value.end(), ')'), value.end());
+      return true;
+    }
+  }
+  return false;
+}
+//-------------------------------------------------------------------
+
+
+//-------------------------------------------------------------------
+void
+GetValuesFromValue(const std::string & s,
+                   std::vector<std::string> & values)
+{
+  std::stringstream strstr(s);
+  std::istream_iterator<std::string> it(strstr);
+  std::istream_iterator<std::string> end;
+  std::vector<std::string> results(it, end);
+  values.clear();
+  values.resize(results.size());
+  for(uint i=0; i<results.size(); i++) values[i] = results[i];
+}
+//-------------------------------------------------------------------
+
+
+//-------------------------------------------------------------------
+template<unsigned int Dimension>
+typename itk::Matrix<double, Dimension+1, Dimension+1>
+createMatrixFromElastixFile(std::vector<std::string> & filename, bool verbose=true) {
+  if (Dimension != 3) {
+    FATAL("Only 3D yet" << std::endl);
+  }
+  typename itk::Matrix<double, Dimension+1, Dimension+1> matrix;
+
+  itk::Euler3DTransform<double>::Pointer mat = itk::Euler3DTransform<double>::New();
+  itk::Euler3DTransform<double>::Pointer previous;
+  for(uint j=0; j<filename.size(); j++) {
+
+    // Open file
+    if (verbose) std::cout << "Read elastix parameters in " << filename[j] << std::endl;
+    std::ifstream is;
+    clitk::openFileForReading(is, filename[j]);
+
+    // Check Transform
+    std::string s;
+    bool b = GetElastixValueFromTag(is, "Transform ", s);
+    if (!b) {
+      FATAL("Error must read 'Transform' in " << filename[j] << std::endl);
+    }
+    if (s != "EulerTransform") {
+      FATAL("Sorry only 'EulerTransform'" << std::endl);
+    }
+
+    // FIXME check
+    //    (InitialTransformParametersFilename[j] "NoInitialTransform")
+
+    // Get CenterOfRotationPoint
+    GetElastixValueFromTag(is, "CenterOfRotationPoint ", s); // space is needed
+    if (!b) {
+      FATAL("Error must read 'CenterOfRotationPoint' in " << filename[j] << std::endl);
+    }
+    std::vector<std::string> cor;
+    GetValuesFromValue(s, cor);
+    itk::Euler3DTransform<double>::CenterType c;
+    for(uint i=0; i<3; i++)
+      c[i] = atof(cor[i].c_str());
+    mat->SetCenter(c);
+
+    // Get Transformparameters
+    GetElastixValueFromTag(is, "ComputeZYX ", s); // space is needed
+    mat->SetComputeZYX( s==std::string("true") );
+
+    // Get Transformparameters
+    GetElastixValueFromTag(is, "TransformParameters ", s); // space is needed
+    if (!b) {
+      FATAL("Error must read 'TransformParameters' in " << filename[j] << std::endl);
+    }
+    std::vector<std::string> results;
+    GetValuesFromValue(s, results);
+
+    // construct a stream from the string
+    itk::Euler3DTransform<double>::ParametersType p;
+    p.SetSize(6);
+    for(uint i=0; i<3; i++)
+      p[i] = atof(results[i].c_str()); // Rotation
+    for(uint i=0; i<3; i++)
+      p[i+3] = atof(results[i+3].c_str()); // Translation
+    mat->SetParameters(p);
+
+    if (verbose) {
+      std::cout << "Rotation      (deg) : " << rad2deg(p[0]) << " " << rad2deg(p[1]) << " " << rad2deg(p[2]) << std::endl;
+      std::cout << "Center of rot (phy) : " << c[0] << " " << c[1] << " " << c[2] << std::endl;
+      std::cout << "Translation   (phy) : " << p[3] << " " << p[4] << " " << p[5] << std::endl;
+    }
+
+    // Compose with previous if needed
+    if (j!=0) {
+      mat->Compose(previous);
+      if (verbose) {
+        std::cout << "Composed rotation      (deg) : " << rad2deg(mat->GetAngleX()) << " " << rad2deg(mat->GetAngleY()) << " " << rad2deg(mat->GetAngleZ()) << std::endl;
+        std::cout << "Composed center of rot (phy) : " << mat->GetCenter() << std::endl;
+        std::cout << "Compsoed translation   (phy) : " << mat->GetTranslation() << std::endl;
+      }
+    }
+    // previous = mat->Clone(); // ITK4
+    previous = itk::Euler3DTransform<double>::New();
+    previous->SetParameters(mat->GetParameters());
+    previous->SetCenter(c);
+    previous->SetComputeZYX(mat->GetComputeZYX());
+  }
+
+  mat = previous;
+  for(uint i=0; i<3; i++)
+    for(uint j=0; j<3; j++)
+      matrix[i][j] = mat->GetMatrix()[i][j];
+  // Offset is -Rc + t + c
+  matrix[0][3] = mat->GetOffset()[0];
+  matrix[1][3] = mat->GetOffset()[1];
+  matrix[2][3] = mat->GetOffset()[2];
+  matrix[3][3] = 1;
+
+  return matrix;
+}
+}
+//-------------------------------------------------------------------
+
+#endif
diff --git a/common/clitkMatrix.cxx b/common/clitkMatrix.cxx
new file mode 100644 (file)
index 0000000..c911f55
--- /dev/null
@@ -0,0 +1,71 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+#include "clitkMatrix.h"
+
+//--------------------------------------------------------------------
+namespace clitk {
+
+//-------------------------------------------------------------------
+std::string
+Get4x4MatrixDoubleAsString(vtkMatrix4x4 *matrix,
+                           const int precision)
+{
+  std::ostringstream strmatrix;
+
+  // Figure out the number of digits of the integer part of the largest absolute value
+  // for each column
+  unsigned width[4];
+  for (unsigned int j = 0; j < 4; j++){
+    double absmax = 0.;
+    for (unsigned int i = 0; i < 4; i++)
+      absmax = std::max(absmax, vnl_math_abs(matrix->GetElement(i, j)));
+    unsigned ndigits = (unsigned)std::max(0.,std::log10(absmax))+1;
+    width[j] = precision+ndigits+3;
+  }
+
+  // Output with correct width, aligned to the right
+  for (unsigned int i = 0; i < 4; i++) {
+    for (unsigned int j = 0; j < 4; j++) {
+      strmatrix.setf(ios::fixed,ios::floatfield);
+      strmatrix.precision(precision);
+      strmatrix.fill(' ');
+      strmatrix.width(width[j]);
+      strmatrix << std::right << matrix->GetElement(i, j);
+    }
+    strmatrix << std::endl;
+  }
+  std::string result = strmatrix.str().c_str();
+  return result;
+}
+//-------------------------------------------------------------------
+
+//-------------------------------------------------------------------
+std::string
+Get4x4MatrixDoubleAsString(itk::Matrix<double, 4, 4> m,
+                           const int precision)
+{
+  vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
+  for (unsigned int j = 0; j < 4; j++)
+    for (unsigned int i = 0; i < 4; i++)
+      matrix->SetElement(j,i,m[j][i]);
+  return Get4x4MatrixDoubleAsString(matrix, precision);
+}
+//-------------------------------------------------------------------
+}
+//-------------------------------------------------------------------
diff --git a/common/clitkMatrix.h b/common/clitkMatrix.h
new file mode 100644 (file)
index 0000000..25b0fa1
--- /dev/null
@@ -0,0 +1,39 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+#ifndef clitkMatrix_h
+#define clitkMatrix_h
+
+#include <itkMatrix.h>
+#define VTK_EXCLUDE_STRSTREAM_HEADERS
+#include <vtkMatrix4x4.h>
+#include <vtkSmartPointer.h>
+
+//--------------------------------------------------------------------
+namespace clitk {
+std::string
+Get4x4MatrixDoubleAsString(vtkMatrix4x4 *matrix,
+                           const int precision=3);
+
+std::string
+Get4x4MatrixDoubleAsString(itk::Matrix<double, 4, 4> m,
+                           const int precision=3);
+}
+//-------------------------------------------------------------------
+
+#endif
index d3644b19206f830eab30397f2c209ef721eca6f4..562ed63a67e11facfdcc07ff960fd5456394613a 100644 (file)
@@ -23,6 +23,7 @@
 #include "itkPoint.h"
 #include "clitkImageCommon.h"
 #include "clitkCommon.h"
+#define VTK_EXCLUDE_STRSTREAM_HEADERS
 #include <vtkMatrix4x4.h>
 #include <vtkSmartPointer.h>
  
index 7240be82c4ef5843a221ed34930d4b0691dc8ea5..10ffc865fa2ed353605e4844abd6c456e5e678ee 100644 (file)
@@ -23,6 +23,7 @@
 #include <itkObjectFactory.h>
 #include <itkProcessObject.h>
 
+#define VTK_EXCLUDE_STRSTREAM_HEADERS
 #include <vtkSmartPointer.h>
 #include <vtkTransform.h>
 
index ddc4ad3833ae2e60050fee3debd5c58e106ee4c7..23c78f155dd9e4c51ddad251cf87c549e6d7b70c 100644 (file)
@@ -22,6 +22,7 @@
 #include "vvImageReader.h"
 #include "vvImageReader.txx"
 #include "clitkTransformUtilities.h"
+#include "clitkElastix.h"
 
 //------------------------------------------------------------------------------
 vvImageReader::vvImageReader()
@@ -150,18 +151,20 @@ void vvImageReader::ReadMatImageTransform()
 {
   std::string filename(mInputFilenames[0]);
   std::string ext(itksys::SystemTools::GetFilenameLastExtension(filename));
+
+  // Try a ".mat" extension
   if (ext.length() > 0) {
     size_t pos = filename.rfind(ext);
     filename.replace(pos, ext.length(), ".mat");
   }
   else
     filename += ".mat";
-    
   std::ifstream f(filename.c_str());
+  itk::Matrix<double, 4, 4> itkMat;
+  bool itkMatRead = false;
   if(f.is_open()) {
-    f.close();
+    itkMatRead = true;
 
-    itk::Matrix<double, 4, 4> itkMat;
     itkMat.SetIdentity();
     try {
       itkMat = clitk::ReadMatrix3D(filename);
@@ -169,8 +172,29 @@ void vvImageReader::ReadMatImageTransform()
     catch (itk::ExceptionObject & err) {
       itkWarningMacro(<< "Found " << filename
                       << " but this is not a 4x4 matrix so it is ignored.");
+      itkMatRead = false;
     }
+  }
+  f.close();
+
+  // Try a ".elx" extension
+  filename = mInputFilenames[0];
+  if (ext.length() > 0) {
+    size_t pos = filename.rfind(ext);
+    filename.replace(pos, ext.length(), ".elx");
+  }
+  else
+    filename += ".elx";
+  f.open(filename.c_str());
+  if(!itkMatRead && f.is_open()) {
+    itkMatRead = true;
+    std::vector<std::string> l;
+    l.push_back(filename);
+    itkMat = clitk::createMatrixFromElastixFile<3>(l, true);
+  }
+  f.close();
 
+  if(itkMatRead) {
     vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
     matrix->Identity();
     for(int j=0; j<4; j++)
@@ -208,12 +232,12 @@ void vvImageReader::ReadMatImageTransform()
     //for image sequences, apply the transform to each images of the sequence
     if (mImage->IsTimeSequence())
     {
-       for (unsigned i = 1 ; i<mImage->GetTransform().size() ; i++)
-        {
-            mImage->GetTransform()[i]->PreMultiply();
-            mImage->GetTransform()[i]->Concatenate(matrix);
-            mImage->GetTransform()[i]->Update();
-        }
+      for (unsigned i = 1 ; i<mImage->GetTransform().size() ; i++)
+      {
+        mImage->GetTransform()[i]->PreMultiply();
+        mImage->GetTransform()[i]->Concatenate(matrix);
+        mImage->GetTransform()[i]->Update();
+      }
     }
 
   }
index 17b7c21fce67e7f95f5b44e004d4e598caeda384..cf0645f15afcde53a53e8b3fb70d2da847d2d27a 100644 (file)
@@ -1,7 +1,7 @@
 /*=========================================================================
   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
-  Authors belong to: 
+  Authors belong to:
   - University of LYON              http://www.universite-lyon.fr/
   - Léon Bérard cancer center       http://www.centreleonberard.fr
   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
 #include "clitkFilterBase.h"
 #include "clitkCropLikeImageFilter.h"
 #include "clitkSegmentationUtils.h"
-// #include "itkLabelOverlapMeasuresImageFilter.h"
 
 // itk
 #include <itkImageToImageFilter.h>
 #include <itkLabelStatisticsImageFilter.h>
+#include <itkLabelOverlapMeasuresImageFilter.h>
 
 #include <iomanip>
 
 namespace clitk {
-  
+
   //--------------------------------------------------------------------
   /*
     Analyze the relative position of a Target (mask image) according
     to some Object, in a given Support. Indicate the main important
-    position of this Target according the Object. 
+    position of this Target according the Object.
   */
   //--------------------------------------------------------------------
-  
+
   template <class ImageType>
   class LabelImageOverlapMeasureFilter:
     public virtual FilterBase,
@@ -53,30 +53,30 @@ namespace clitk {
     typedef LabelImageOverlapMeasureFilter<ImageType>          Self;
     typedef itk::SmartPointer<Self>                            Pointer;
     typedef itk::SmartPointer<const Self>                      ConstPointer;
-       
+
     /** Method for creation through the object factory. */
     itkNewMacro(Self);
-    
+
     /** Run-time type information (and related methods). */
     itkTypeMacro(LabelImageOverlapMeasureFilter, ImageToImageFilter);
 
     /** Some convenient typedefs. */
     typedef typename ImageType::ConstPointer ImageConstPointer;
     typedef typename ImageType::Pointer      ImagePointer;
-    typedef typename ImageType::RegionType   RegionType; 
+    typedef typename ImageType::RegionType   RegionType;
     typedef typename ImageType::PixelType    PixelType;
     typedef typename ImageType::SpacingType  SpacingType;
     typedef typename ImageType::SizeType     SizeType;
     typedef typename ImageType::IndexType    IndexType;
     typedef typename ImageType::PointType    PointType;
-    
+
     /** ImageDimension constants */
     itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
     FILTERBASE_INIT;
+
     // Options
     itkGetConstMacro(BackgroundValue, PixelType);
-    itkSetMacro(BackgroundValue, PixelType);
+    //itkSetMacro(BackgroundValue, PixelType);
 
     itkGetConstMacro(Label1, PixelType);
     itkSetMacro(Label1, PixelType);
@@ -84,18 +84,28 @@ namespace clitk {
     itkGetConstMacro(Label2, PixelType);
     itkSetMacro(Label2, PixelType);
 
+    itkSetMacro(VerboseFlag, bool);
+    itkGetConstMacro(VerboseFlag, bool);
+    itkBooleanMacro(VerboseFlag);
+
+    itkSetMacro(LongFlag, bool);
+    itkGetConstMacro(LongFlag, bool);
+    itkBooleanMacro(LongFlag);
+
     // I dont want to verify inputs information
     virtual void VerifyInputInformation() { }
-    
+
    protected:
     LabelImageOverlapMeasureFilter();
     virtual ~LabelImageOverlapMeasureFilter() {}
-    
+
     PixelType m_BackgroundValue;
     PixelType m_Label1;
     PixelType m_Label2;
     ImagePointer m_Input1;
     ImagePointer m_Input2;
+    bool m_VerboseFlag;
+    bool m_LongFlag;
 
     virtual void GenerateOutputInformation();
     virtual void GenerateInputRequestedRegion();
@@ -104,7 +114,7 @@ namespace clitk {
   private:
     LabelImageOverlapMeasureFilter(const Self&); //purposely not implemented
     void operator=(const Self&); //purposely not implemented
-    
+
   }; // end class
   //--------------------------------------------------------------------
 
index 037570916b0346be55ed56ff47cf1988485db821..e62a1a9f4c0916bd353b062f921001d3b98312ac 100644 (file)
@@ -1,7 +1,7 @@
 /*=========================================================================
   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
-  Authors belong to: 
+  Authors belong to:
   - University of LYON              http://www.universite-lyon.fr/
   - Léon Bérard cancer center       http://www.centreleonberard.fr
   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
@@ -26,17 +26,19 @@ LabelImageOverlapMeasureFilter():
   this->SetNumberOfRequiredInputs(2);
   SetLabel1(1);
   SetLabel2(1);
-  SetBackgroundValue(0);
+  m_BackgroundValue = 0;
+  SetVerboseFlag(false);
+  SetLongFlag(false);
 }
 //--------------------------------------------------------------------
 
 
 //--------------------------------------------------------------------
 template <class ImageType>
-void 
+void
 clitk::LabelImageOverlapMeasureFilter<ImageType>::
-GenerateOutputInformation() 
-{ 
+GenerateOutputInformation()
+{
   // DD("GenerateOutputInformation");
   //ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
   // ImagePointer outputImage = this->GetOutput(0);
@@ -47,9 +49,9 @@ GenerateOutputInformation()
 
 //--------------------------------------------------------------------
 template <class ImageType>
-void 
+void
 clitk::LabelImageOverlapMeasureFilter<ImageType>::
-GenerateInputRequestedRegion() 
+GenerateInputRequestedRegion()
 {
   // Call default
   itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
@@ -63,12 +65,10 @@ GenerateInputRequestedRegion()
 
 //--------------------------------------------------------------------
 template <class ImageType>
-void 
+void
 clitk::LabelImageOverlapMeasureFilter<ImageType>::
-GenerateData() 
+GenerateData()
 {
-  // DD("GenerateData");
-
   // Get input pointer
   m_Input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
   m_Input2 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
@@ -86,60 +86,14 @@ GenerateData()
   // Resize like the union
   ImagePointer input1 = clitk::ResizeImageLike<ImageType>(m_Input1, bbo, GetBackgroundValue());
   ImagePointer input2 = clitk::ResizeImageLike<ImageType>(m_Input2, bbo, GetBackgroundValue());
-  //DD(input1->GetLargestPossibleRegion());
-  //DD(input2->GetLargestPossibleRegion());
-
-  // Compute overlap image
-  ImagePointer image_union = clitk::Clone<ImageType>(input1);
-  ImagePointer image_intersection = clitk::Clone<ImageType>(input1);
-  clitk::Or<ImageType>(image_union, input2, GetBackgroundValue());
-  clitk::And<ImageType>(image_intersection, input2, GetBackgroundValue());
-
-  ImagePointer image_1NotIn2 = clitk::Clone<ImageType>(input1);
-  clitk::AndNot<ImageType>(image_1NotIn2, input2, GetBackgroundValue());
-  
-  ImagePointer image_2NotIn1 = clitk::Clone<ImageType>(input2);
-  clitk::AndNot<ImageType>(image_2NotIn1, input1, GetBackgroundValue());
-
-  //writeImage<ImageType>(image_union, "union.mha");
-  //writeImage<ImageType>(image_intersection, "intersection.mha");
-  //writeImage<ImageType>(image_1NotIn2, "image_1NotIn2.mha");
-  //writeImage<ImageType>(image_2NotIn1, "image_2NotIn1.mha");
-  
-  // Compute size
-  typedef itk::LabelStatisticsImageFilter<ImageType, ImageType> StatFilterType;
-  typename StatFilterType::Pointer statFilter = StatFilterType::New();
-  statFilter->SetInput(image_union);
-  statFilter->SetLabelInput(image_union);
-  statFilter->Update();
-  int u = statFilter->GetCount(GetLabel1());
-
-  statFilter->SetInput(image_intersection);
-  statFilter->SetLabelInput(image_intersection);
-  statFilter->Update();
-  int inter = statFilter->GetCount(GetLabel1());
-  
-  statFilter->SetInput(m_Input1);
-  statFilter->SetLabelInput(m_Input1);
-  statFilter->Update();
-  int in1 = statFilter->GetCount(GetLabel1());
-
-  statFilter->SetInput(m_Input2);
-  statFilter->SetLabelInput(m_Input2);
-  statFilter->Update();
-  int in2 = statFilter->GetCount(GetLabel1());
-
-  statFilter->SetInput(image_1NotIn2);
-  statFilter->SetLabelInput(image_1NotIn2);
-  statFilter->Update();
-  int l1notIn2 = statFilter->GetCount(GetLabel1());
-
-  statFilter->SetInput(image_2NotIn1);
-  statFilter->SetLabelInput(image_2NotIn1);
-  statFilter->Update();
-  int l2notIn1 = statFilter->GetCount(GetLabel1());
-
-  double dice = 2.0*(double)inter/(double)(in1+in2);
+  /*
+    if (GetVerboseFlag()) {
+    std::cout << "Resize images to the union of bounding boxes: "
+    <<  input1->GetLargestPossibleRegion().GetSize() << std::endl;
+    }
+  */
+
+  /*
   int width = 6;
   std::cout << std::setw(width) << in1 << " "
             << std::setw(width) << in2 << " "
@@ -148,6 +102,38 @@ GenerateData()
             << std::setw(width) << l1notIn2  << " "
             << std::setw(width) << l2notIn1  << " "
             << std::setw(width) << dice << " "; //std::endl;
+  */
+
+  // Compute overlap, dice
+  typedef itk::LabelOverlapMeasuresImageFilter<ImageType> FilterType;
+  typename FilterType::Pointer diceFilter = FilterType::New();
+  diceFilter->SetSourceImage(input1);
+  diceFilter->SetTargetImage(input2);
+  diceFilter->Update();
+
+  // Display information
+  if (!GetLongFlag()) {
+    if (GetVerboseFlag()) {
+      std::cout << "Dice : ";
+    }
+    std::cout << diceFilter->GetDiceCoefficient() << std::endl;
+  }
+  else { // long options
+    if (GetVerboseFlag()) {
+      std::cout << "Dice     Jaccard   Source Target Inter  Union   SrComp TarComp" << std::endl;
+    }
+    typename FilterType::MapType m = diceFilter->GetLabelSetMeasures();
+    int width = 6;
+    std::cout << std::setw(width) << diceFilter->GetDiceCoefficient() << " "
+              << std::setw(width) << diceFilter->GetJaccardCoefficient() << " "
+              << std::setw(width) << m[m_Label1].m_Source << " "
+              << std::setw(width) << m[m_Label2].m_Target << " "
+              << std::setw(width) << m[m_Label1].m_Intersection << " "
+              << std::setw(width) << m[m_Label1].m_Union << " "
+              << std::setw(width) << m[m_Label1].m_SourceComplement << " "
+              << std::setw(width) << m[m_Label2].m_TargetComplement << " "
+              << std::endl;
+  }
+
 }
 //--------------------------------------------------------------------
-
index a3f88beb3db8443f08fa376da1480433f24e4051..ddaa8a077b41f2ffcf2456836c2eeb7a4f0119fc 100644 (file)
@@ -222,12 +222,19 @@ GenerateData()
     std::cout << "LastDimIsTime  = " << m_LastDimensionIsTime << std::endl;
   }
 
+  // Compute origin based on image corner
+  typename FilterType::OriginPointType origin = input->GetOrigin();
+  for(unsigned int i=0; i<OutputImageType::ImageDimension; i++) {
+    origin[i] -= 0.5 * input->GetSpacing()[i];
+    origin[i] += 0.5 * m_OutputSpacing[i];
+  }
+
   // Instance of the transform object to be passed to the resample
   // filter. By default, identity transform is applied
   filter->SetTransform(m_Transform);
   filter->SetSize(m_OutputSize);
   filter->SetOutputSpacing(m_OutputSpacing);
-  filter->SetOutputOrigin(input->GetOrigin());
+  filter->SetOutputOrigin(origin);
   filter->SetDefaultPixelValue(m_DefaultPixelValue);
   filter->SetNumberOfThreads(this->GetNumberOfThreads()); 
   filter->SetOutputDirection(input->GetDirection()); // <-- NEEDED if we want to keep orientation (in case of PermutAxes for example)
diff --git a/itk/itkLabelOverlapMeasuresImageFilter.h b/itk/itkLabelOverlapMeasuresImageFilter.h
deleted file mode 100644 (file)
index 978fed3..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*=========================================================================
-
-  Program:   Insight Segmentation & Registration Toolkit
-  Module:    $RCSfile: itkLabelOverlapMeasuresImageFilter.h,v $
-  Language:  C++
-  Date:      $Date: $
-  Version:   $Revision: $
-
-  Copyright (c) Insight Software Consortium. All rights reserved.
-  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#ifndef __itkLabelOverlapMeasuresImageFilter_h
-#define __itkLabelOverlapMeasuresImageFilter_h
-
-#include "itkImageToImageFilter.h"
-#include "itkFastMutexLock.h"
-#include "itkNumericTraits.h"
-
-//#include "itk_hash_map.h"
-#include "itksys/hash_map.hxx"
-
-namespace itk {
-
-/** \class LabelOverlapMeasuresImageFilter
- * \brief Computes overlap measures between the set same set of labels of
- * pixels of two images.  Background is assumed to be 0.
- *
- * \sa LabelOverlapMeasuresImageFilter
- *
- * \ingroup MultiThreaded
- */
-template<class TLabelImage>
-class ITK_EXPORT LabelOverlapMeasuresImageFilter :
-    public ImageToImageFilter<TLabelImage, TLabelImage>
-{
-public:
-  /** Standard Self typedef */
-  typedef LabelOverlapMeasuresImageFilter                Self;
-  typedef ImageToImageFilter<TLabelImage,TLabelImage>    Superclass;
-  typedef SmartPointer<Self>                             Pointer;
-  typedef SmartPointer<const Self>                       ConstPointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro( Self );
-
-  /** Runtime information support. */
-  itkTypeMacro( LabelOverlapMeasuresImageFilter, ImageToImageFilter );
-
-    virtual void VerifyInputInformation() { }
-
-
-  /** Image related typedefs. */
-  typedef TLabelImage                                   LabelImageType;
-  typedef typename TLabelImage::Pointer                 LabelImagePointer;
-  typedef typename TLabelImage::ConstPointer            LabelImageConstPointer;
-
-  typedef typename TLabelImage::RegionType              RegionType;
-  typedef typename TLabelImage::SizeType                SizeType;
-  typedef typename TLabelImage::IndexType               IndexType;
-
-  typedef typename TLabelImage::PixelType               LabelType;
-
-  /** Type to use form computations. */
-  typedef typename NumericTraits<LabelType>::RealType RealType;
-
-  /** \class LabelLabelOverlapMeasuress
-   * \brief Metrics stored per label */
-  class LabelSetMeasures
-    {
-    public:
-    // default constructor
-    LabelSetMeasures()
-      {
-      m_Source = 0;
-      m_Target = 0;
-      m_Union = 0;
-      m_Intersection = 0;
-      m_SourceComplement = 0;
-      m_TargetComplement = 0;
-      }
-
-  // added for completeness
-    LabelSetMeasures& operator=( const LabelSetMeasures& l )
-      {
-      m_Source = l.m_Source;
-      m_Target = l.m_Target;
-      m_Union = l.m_Union;
-      m_Intersection = l.m_Intersection;
-      m_SourceComplement = l.m_SourceComplement;
-      m_TargetComplement = l.m_TargetComplement;
-      }
-
-    unsigned long m_Source;
-    unsigned long m_Target;
-    unsigned long m_Union;
-    unsigned long m_Intersection;
-    unsigned long m_SourceComplement;
-    unsigned long m_TargetComplement;
-    };
-
-  /** Type of the map used to store data per label */
-  typedef itksys::hash_map<LabelType, LabelSetMeasures> MapType;
-  typedef typename MapType::iterator MapIterator;
-  typedef typename MapType::const_iterator MapConstIterator;
-
-  /** Image related typedefs. */
-  itkStaticConstMacro( ImageDimension, unsigned int,
-    TLabelImage::ImageDimension );
-
-  /** Set the source image. */
-  void SetSourceImage( const LabelImageType * image )
-    { this->SetNthInput( 0, const_cast<LabelImageType *>( image ) ); }
-
-  /** Set the target image. */
-  void SetTargetImage( const LabelImageType * image )
-    { this->SetNthInput( 1, const_cast<LabelImageType *>( image ) ); }
-
-  /** Get the source image. */
-  const LabelImageType * GetSourceImage( void )
-    { return this->GetInput( 0 ); }
-
-  /** Get the target image. */
-  const LabelImageType * GetTargetImage( void )
-    { return this->GetInput( 1 ); }
-
-  /** Get the label set measures */
-  MapType GetLabelSetMeasures()
-    { return this->m_LabelSetMeasures; }
-
-  /**
-   * tric overlap measures
-   */
-  /** measures over all labels */
-  RealType GetTotalOverlap();
-  RealType GetUnionOverlap();
-  RealType GetMeanOverlap();
-  RealType GetVolumeSimilarity();
-  RealType GetFalseNegativeError();
-  RealType GetFalsePositiveError();
-  /** measures over individual labels */
-  RealType GetTargetOverlap( LabelType );
-  RealType GetUnionOverlap( LabelType );
-  RealType GetMeanOverlap( LabelType );
-  RealType GetVolumeSimilarity( LabelType );
-  RealType GetFalseNegativeError( LabelType );
-  RealType GetFalsePositiveError( LabelType );
-  /** alternative names */
-  RealType GetJaccardCoefficient()
-    { return this->GetUnionOverlap(); }
-  RealType GetJaccardCoefficient( LabelType label )
-    { return this->GetUnionOverlap( label ); }
-  RealType GetDiceCoefficient()
-    { return this->GetMeanOverlap(); }
-  RealType GetDiceCoefficient( LabelType label )
-    { return this->GetMeanOverlap( label ); }
-
-
-#ifdef ITK_USE_CONCEPT_CHECKING
-  /** Begin concept checking */
-  itkConceptMacro( Input1HasNumericTraitsCheck,
-    ( Concept::HasNumericTraits<LabelType> ) );
-  /** End concept checking */
-#endif
-
-protected:
-  LabelOverlapMeasuresImageFilter();
-  ~LabelOverlapMeasuresImageFilter(){};
-  void PrintSelf( std::ostream& os, Indent indent ) const;
-
-  /**
-   * Pass the input through unmodified. Do this by setting the output to the
-   * source this by setting the output to the source image in the
-   * AllocateOutputs() method.
-   */
-  void AllocateOutputs();
-
-  void BeforeThreadedGenerateData();
-
-  void AfterThreadedGenerateData();
-
-  /** Multi-thread version GenerateData. */
-  void ThreadedGenerateData( const RegionType&, int );
-
-  // Override since the filter needs all the data for the algorithm
-  void GenerateInputRequestedRegion();
-
-  // Override since the filter produces all of its output
-  void EnlargeOutputRequestedRegion( DataObject *data );
-
-private:
-  LabelOverlapMeasuresImageFilter( const Self& ); //purposely not implemented
-  void operator=( const Self& ); //purposely not implemented
-
-  std::vector<MapType>                            m_LabelSetMeasuresPerThread;
-  MapType                                         m_LabelSetMeasures;
-
-  SimpleFastMutexLock                             m_Mutex;
-
-}; // end of class
-
-} // end namespace itk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "itkLabelOverlapMeasuresImageFilter.txx"
-#endif
-
-#endif
diff --git a/itk/itkLabelOverlapMeasuresImageFilter.txx b/itk/itkLabelOverlapMeasuresImageFilter.txx
deleted file mode 100644 (file)
index ced277b..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-/*=========================================================================
-
-  Program:   Insight Segmentation & Registration Toolkit
-  Module:    $RCSfile: itkLabelOverlapMeasuresImageFilter.txx,v $
-  Language:  C++
-  Date:      $Date: $
-  Version:   $Revision: $
-
-  Copyright (c) Insight Software Consortium. All rights reserved.
-  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#ifndef _itkLabelOverlapMeasuresImageFilter_txx
-#define _itkLabelOverlapMeasuresImageFilter_txx
-
-#include "itkLabelOverlapMeasuresImageFilter.h"
-
-#include "itkImageRegionConstIterator.h"
-#include "itkProgressReporter.h"
-
-namespace itk {
-
-#if defined(__GNUC__) && (__GNUC__ <= 2) //NOTE: This class needs a mutex for gnu 2.95
-/** Used for mutex locking */
-#define LOCK_HASHMAP this->m_Mutex.Lock()
-#define UNLOCK_HASHMAP this->m_Mutex.Unlock()
-#else
-#define LOCK_HASHMAP
-#define UNLOCK_HASHMAP
-#endif
-
-template<class TLabelImage>
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::LabelOverlapMeasuresImageFilter()
-{
-  // this filter requires two input images
-  this->SetNumberOfRequiredInputs( 2 );
-}
-
-template<class TLabelImage>
-void
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GenerateInputRequestedRegion()
-{
-  Superclass::GenerateInputRequestedRegion();
-  if( this->GetSourceImage() )
-    {
-    LabelImagePointer source = const_cast
-      <LabelImageType *>( this->GetSourceImage() );
-    source->SetRequestedRegionToLargestPossibleRegion();
-    }
-  if( this->GetTargetImage() )
-    {
-    LabelImagePointer target = const_cast
-      <LabelImageType *>( this->GetTargetImage() );
-    target->SetRequestedRegionToLargestPossibleRegion();
-    }
-}
-
-template<class TLabelImage>
-void
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::EnlargeOutputRequestedRegion( DataObject *data )
-{
-  Superclass::EnlargeOutputRequestedRegion( data );
-  data->SetRequestedRegionToLargestPossibleRegion();
-}
-
-
-template<class TLabelImage>
-void
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::AllocateOutputs()
-{
-  // Pass the source through as the output
-  LabelImagePointer image =
-    const_cast<TLabelImage *>( this->GetSourceImage() );
-  this->SetNthOutput( 0, image );
-
-  // Nothing that needs to be allocated for the remaining outputs
-}
-
-template<class TLabelImage>
-void
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::BeforeThreadedGenerateData()
-{
-  int numberOfThreads = this->GetNumberOfThreads();
-
-  // Resize the thread temporaries
-  this->m_LabelSetMeasuresPerThread.resize( numberOfThreads );
-
-  // Initialize the temporaries
-  for( int n = 0; n < numberOfThreads; n++ )
-    {
-    this->m_LabelSetMeasuresPerThread[n].clear();
-    }
-
-  // Initialize the final map
-  this->m_LabelSetMeasures.clear();
-}
-
-template<class TLabelImage>
-void
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::AfterThreadedGenerateData()
-{
-  // Run through the map for each thread and accumulate the set measures.
-  for( int n = 0; n < this->GetNumberOfThreads(); n++ )
-    {
-    // iterate over the map for this thread
-    for( MapConstIterator threadIt = this->m_LabelSetMeasuresPerThread[n].begin();
-      threadIt != this->m_LabelSetMeasuresPerThread[n].end();
-      ++threadIt )
-      {
-      // does this label exist in the cumulative stucture yet?
-      MapIterator mapIt = this->m_LabelSetMeasures.find( ( *threadIt ).first );
-      if( mapIt == this->m_LabelSetMeasures.end() )
-        {
-        // create a new entry
-        typedef typename MapType::value_type MapValueType;
-        mapIt = this->m_LabelSetMeasures.insert( MapValueType(
-          (*threadIt).first, LabelSetMeasures() ) ).first;
-        }
-
-      // accumulate the information from this thread
-      (*mapIt).second.m_Source += (*threadIt).second.m_Source;
-      (*mapIt).second.m_Target += (*threadIt).second.m_Target;
-      (*mapIt).second.m_Union += (*threadIt).second.m_Union;
-      (*mapIt).second.m_Intersection +=
-        (*threadIt).second.m_Intersection;
-      (*mapIt).second.m_SourceComplement +=
-        (*threadIt).second.m_SourceComplement;
-      (*mapIt).second.m_TargetComplement +=
-        (*threadIt).second.m_TargetComplement;
-      } // end of thread map iterator loop
-    } // end of thread loop
-}
-
-template<class TLabelImage>
-void
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::ThreadedGenerateData( const RegionType& outputRegionForThread,
-  int threadId )
-{
-  ImageRegionConstIterator<LabelImageType> ItS( this->GetSourceImage(),
-    outputRegionForThread );
-  ImageRegionConstIterator<LabelImageType> ItT( this->GetTargetImage(),
-    outputRegionForThread );
-
-  // support progress methods/callbacks
-  ProgressReporter progress( this, threadId,
-    2*outputRegionForThread.GetNumberOfPixels() );
-
-  for( ItS.GoToBegin(), ItT.GoToBegin(); !ItS.IsAtEnd(); ++ItS, ++ItT )
-    {
-    LabelType sourceLabel = ItS.Get();
-    LabelType targetLabel = ItT.Get();
-
-    // is the label already in this thread?
-    MapIterator mapItS =
-      this->m_LabelSetMeasuresPerThread[threadId].find( sourceLabel );
-    MapIterator mapItT =
-      this->m_LabelSetMeasuresPerThread[threadId].find( targetLabel );
-
-    if( mapItS == this->m_LabelSetMeasuresPerThread[threadId].end() )
-      {
-      // create a new label set measures object
-      typedef typename MapType::value_type MapValueType;
-      LOCK_HASHMAP;
-      mapItS = this->m_LabelSetMeasuresPerThread[threadId].insert(
-        MapValueType( sourceLabel, LabelSetMeasures() ) ).first;
-      UNLOCK_HASHMAP;
-      }
-
-    if( mapItT == this->m_LabelSetMeasuresPerThread[threadId].end() )
-      {
-      // create a new label set measures object
-      typedef typename MapType::value_type MapValueType;
-      LOCK_HASHMAP;
-      mapItT = this->m_LabelSetMeasuresPerThread[threadId].insert(
-        MapValueType( targetLabel, LabelSetMeasures() ) ).first;
-      UNLOCK_HASHMAP;
-      }
-
-    (*mapItS).second.m_Source++;
-    (*mapItT).second.m_Target++;
-
-    if( sourceLabel == targetLabel )
-      {
-      (*mapItS).second.m_Intersection++;
-      (*mapItS).second.m_Union++;
-      }
-    else
-      {
-      (*mapItS).second.m_Union++;
-      (*mapItT).second.m_Union++;
-
-      (*mapItS).second.m_SourceComplement++;
-      (*mapItT).second.m_TargetComplement++;
-      }
-
-    progress.CompletedPixel();
-    }
-}
-
-/**
- *  measures
- */
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetTotalOverlap()
-{
-  RealType numerator = 0.0;
-  RealType denominator = 0.0;
-  for( MapIterator mapIt = this->m_LabelSetMeasures.begin();
-    mapIt != this->m_LabelSetMeasures.end(); ++mapIt )
-    {
-    // Do not include the background in the final value.
-    if( (*mapIt).first == NumericTraits<LabelType>::Zero )
-      {
-      continue;
-      }
-    numerator += static_cast<RealType>( (*mapIt).second.m_Intersection );
-    denominator += static_cast<RealType>( (*mapIt).second.m_Target );
-    }
-  return ( numerator / denominator );
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetTargetOverlap( LabelType label )
-{
-  MapIterator mapIt = this->m_LabelSetMeasures.find( label );
-  if( mapIt == this->m_LabelSetMeasures.end() )
-    {
-    itkWarningMacro( "Label " << label << " not found." );
-    return 0.0;
-    }
-  RealType value =
-    static_cast<RealType>( (*mapIt).second.m_Intersection ) /
-    static_cast<RealType>( (*mapIt).second.m_Target );
-  return value;
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetUnionOverlap()
-{
-  RealType numerator = 0.0;
-  RealType denominator = 0.0;
-  for( MapIterator mapIt = this->m_LabelSetMeasures.begin();
-    mapIt != this->m_LabelSetMeasures.end(); ++mapIt )
-    {
-    // Do not include the background in the final value.
-    if( (*mapIt).first == NumericTraits<LabelType>::Zero )
-      {
-      continue;
-      }
-    numerator += static_cast<RealType>( (*mapIt).second.m_Intersection );
-    denominator += static_cast<RealType>( (*mapIt).second.m_Union );
-    }
-  return ( numerator / denominator );
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetUnionOverlap( LabelType label )
-{
-  MapIterator mapIt = this->m_LabelSetMeasures.find( label );
-  if( mapIt == this->m_LabelSetMeasures.end() )
-    {
-    itkWarningMacro( "Label " << label << " not found." );
-    return 0.0;
-    }
-  RealType value =
-    static_cast<RealType>( (*mapIt).second.m_Intersection ) /
-    static_cast<RealType>( (*mapIt).second.m_Union );
-  return value;
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetMeanOverlap()
-{
-  RealType uo = this->GetUnionOverlap();
-  return ( 2.0 * uo / ( 1.0 + uo ) );
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetMeanOverlap( LabelType label )
-{
-  RealType uo = this->GetUnionOverlap( label );
-  return ( 2.0 * uo / ( 1.0 + uo ) );
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetVolumeSimilarity()
-{
-  RealType numerator = 0.0;
-  RealType denominator = 0.0;
-  for( MapIterator mapIt = this->m_LabelSetMeasures.begin();
-    mapIt != this->m_LabelSetMeasures.end(); ++mapIt )
-    {
-    // Do not include the background in the final value.
-    if( (*mapIt).first == NumericTraits<LabelType>::Zero )
-      {
-      continue;
-      }
-    numerator += ( ( static_cast<RealType>( (*mapIt).second.m_Source ) -
-      static_cast<RealType>( (*mapIt).second.m_Target ) ) );
-    denominator += ( ( static_cast<RealType>( (*mapIt).second.m_Source ) +
-      static_cast<RealType>( (*mapIt).second.m_Target ) ) );
-    }
-  return ( 2.0 * numerator / denominator );
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetVolumeSimilarity( LabelType label )
-{
-  MapIterator mapIt = this->m_LabelSetMeasures.find( label );
-  if( mapIt == this->m_LabelSetMeasures.end() )
-    {
-    itkWarningMacro( "Label " << label << " not found." );
-    return 0.0;
-    }
-  RealType value = 2.0 *
-    ( static_cast<RealType>( (*mapIt).second.m_Source ) -
-      static_cast<RealType>( (*mapIt).second.m_Target ) ) /
-    ( static_cast<RealType>( (*mapIt).second.m_Source ) +
-      static_cast<RealType>( (*mapIt).second.m_Target ) );
-  return value;
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetFalseNegativeError()
-{
-  RealType numerator = 0.0;
-  RealType denominator = 0.0;
-  for( MapIterator mapIt = this->m_LabelSetMeasures.begin();
-    mapIt != this->m_LabelSetMeasures.end(); ++mapIt )
-    {
-    // Do not include the background in the final value.
-    if( (*mapIt).first == NumericTraits<LabelType>::Zero )
-      {
-      continue;
-      }
-    numerator += static_cast<RealType>( (*mapIt).second.m_TargetComplement );
-    denominator += static_cast<RealType>( (*mapIt).second.m_Target );
-    }
-  return ( numerator / denominator );
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetFalseNegativeError( LabelType label )
-{
-  MapIterator mapIt = this->m_LabelSetMeasures.find( label );
-  if( mapIt == this->m_LabelSetMeasures.end() )
-    {
-    itkWarningMacro( "Label " << label << " not found." );
-    return 0.0;
-    }
-  RealType value =
-    static_cast<RealType>( (*mapIt).second.m_TargetComplement ) /
-    static_cast<RealType>( (*mapIt).second.m_Target );
-  return value;
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetFalsePositiveError()
-{
-  RealType numerator = 0.0;
-  RealType denominator = 0.0;
-  for( MapIterator mapIt = this->m_LabelSetMeasures.begin();
-    mapIt != this->m_LabelSetMeasures.end(); ++mapIt )
-    {
-    // Do not include the background in the final value.
-    if( (*mapIt).first == NumericTraits<LabelType>::Zero )
-      {
-      continue;
-      }
-    numerator += static_cast<RealType>( (*mapIt).second.m_SourceComplement );
-    denominator += static_cast<RealType>( (*mapIt).second.m_Source );
-    }
-  return ( numerator / denominator );
-}
-
-template<class TLabelImage>
-typename LabelOverlapMeasuresImageFilter<TLabelImage>::RealType
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::GetFalsePositiveError( LabelType label )
-{
-  MapIterator mapIt = this->m_LabelSetMeasures.find( label );
-  if( mapIt == this->m_LabelSetMeasures.end() )
-    {
-    itkWarningMacro( "Label " << label << " not found." );
-    return 0.0;
-    }
-  RealType value =
-    static_cast<RealType>( (*mapIt).second.m_SourceComplement ) /
-    static_cast<RealType>( (*mapIt).second.m_Source );
-  return value;
-}
-
-template<class TLabelImage>
-void
-LabelOverlapMeasuresImageFilter<TLabelImage>
-::PrintSelf( std::ostream& os, Indent indent ) const
-{
-  Superclass::PrintSelf( os, indent );
-
-}
-
-
-}// end namespace itk
-#endif
index df237735199d9f4b85e38aecd2708c94bdd79ea8..b0710d75af596e8ee39bda4b9207486871921a8b 100644 (file)
@@ -103,13 +103,36 @@ ExternalProject_Add(
 SET(VTK_DIR ${build_prefix}/VTK)
 #=========================================================
 
+#=========================================================
+# GDCM
+   ExternalProject_Add(
+   GDCM
+   SOURCE_DIR ${source_prefix}/gdcm
+   GIT_REPOSITORY git://git.code.sf.net/p/gdcm/gdcm 
+   GIT_TAG v2.2.4
+   INSTALL_COMMAND ""
+   CMAKE_ARGS
+   -DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG}
+   -DCMAKE_C_FLAGS_MINSIZEREL:STRING=${CMAKE_C_FLAGS_MINSIZEREL}
+   -DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE}
+   -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO}
+   -DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG}
+   -DCMAKE_CXX_FLAGS_MINSIZEREL:STRING=${CMAKE_CXX_FLAGS_MINSIZEREL}
+   -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE}
+   -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
+   -DCMAKE_INSTALL_PREFIX:PATH=${INSTALL_PREFIX}
+   -DCMAKE_BUILD_TYPE:STRING=${build_type}
+)
+SET(GDCM_DIR ${build_prefix}/GDCM)
+#=========================================================
+
 #=========================================================
 # ITK
 ExternalProject_Add(
   ITK
   SOURCE_DIR ${source_prefix}/itk
   GIT_REPOSITORY git://itk.org/ITK.git
-  GIT_TAG v4.2.0
+  GIT_TAG v4.4.0
   INSTALL_COMMAND ""
   CMAKE_ARGS
     -DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG}
@@ -148,12 +171,14 @@ endif(MSVC)
 
 ExternalProject_Add(
   VV
-  DEPENDS QT VTK ITK
+  DEPENDS QT VTK ITK GDCM
   SOURCE_DIR ${source_prefix}/vv
   GIT_REPOSITORY git://git.creatis.insa-lyon.fr/clitk
-  INSTALL_COMMAND ${MAKE_COMMAND} package
+  INSTALL_DIR ${install_prefix}
+  INSTALL_COMMAND  make install 
   CMAKE_ARGS
     -DQT_QMAKE_EXECUTABLE:FILEPATH=${qmake_executable}
+    -DGDCM_DIR:PATH=${GDCM_DIR}
     -DITK_DIR:PATH=${ITK_DIR}
     -DVTK_DIR:PATH=${VTK_DIR}
     -DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG}
index 77f12f9f863e301e089cc28c49aab05a20276fe8..6d70fc3e80f0e65b3b9d672997c49b049d915e40 100644 (file)
@@ -24,7 +24,13 @@ ADD_LIBRARY(clitkMIPLib clitkMIPGenericFilter.cxx ${clitkMIP_GGO_C})
 WRAP_GGO(clitkMedianImageFilter_GGO_C clitkMedianImageFilter.ggo)
 ADD_LIBRARY(clitkMedianImageFilterLib clitkMedianImageGenericFilter.cxx ${clitkMedianImageFilter_GGO_C})
 
+#=========================================================
 IF (CLITK_BUILD_TOOLS)
+
+  #=========================================================
+  # install scripts
+  ADD_SUBDIRECTORY(${CLITK_SOURCE_DIR}/cluster_tools ${PROJECT_BINARY_DIR}/cluster_tools)
+
   WRAP_GGO(clitkDicomInfo_GGO_C clitkDicomInfo.ggo)
   ADD_EXECUTABLE(clitkDicomInfo clitkDicomInfo.cxx ${clitkDicomInfo_GGO_C})
   TARGET_LINK_LIBRARIES(clitkDicomInfo clitkCommon)
@@ -89,7 +95,7 @@ IF (CLITK_BUILD_TOOLS)
 
   WRAP_GGO(clitkMedianTemporalDimension_GGO_C clitkMedianTemporalDimension.ggo)
   ADD_EXECUTABLE(clitkMedianTemporalDimension clitkMedianTemporalDimension.cxx
-      ${clitkMedianTemporalDimension_GGO_C})
+    ${clitkMedianTemporalDimension_GGO_C})
   TARGET_LINK_LIBRARIES(clitkMedianTemporalDimension clitkCommon )
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMedianTemporalDimension)
 
@@ -113,13 +119,22 @@ IF (CLITK_BUILD_TOOLS)
   TARGET_LINK_LIBRARIES(clitkElastixTransformToMatrix clitkCommon )
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkElastixTransformToMatrix)
 
+  WRAP_GGO(clitkMatrixToElastixTransform_GGO_C clitkMatrixToElastixTransform.ggo)
+  ADD_EXECUTABLE(clitkMatrixToElastixTransform clitkMatrixToElastixTransform.cxx ${clitkMatrixToElastixTransform_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMatrixToElastixTransform clitkCommon )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMatrixToElastixTransform)
+
+  WRAP_GGO(clitkMatrixInverse_GGO_C clitkMatrixInverse.ggo)
+  ADD_EXECUTABLE(clitkMatrixInverse clitkMatrixInverse.cxx ${clitkMatrixInverse_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMatrixInverse clitkCommon )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMatrixInverse)
 
   WRAP_GGO(clitkSetBackground_GGO_C clitkSetBackground.ggo)
   ADD_EXECUTABLE(clitkSetBackground clitkSetBackground.cxx clitkSetBackgroundGenericFilter.cxx ${clitkSetBackground_GGO_C})
   TARGET_LINK_LIBRARIES(clitkSetBackground clitkCommon)
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkSetBackground)
 
- WRAP_GGO(clitkGammaIndex_GGO_C clitkGammaIndex.ggo)
 WRAP_GGO(clitkGammaIndex_GGO_C clitkGammaIndex.ggo)
   ADD_EXECUTABLE(clitkGammaIndex clitkGammaIndex.cxx ${clitkGammaIndex_GGO_C})
   TARGET_LINK_LIBRARIES(clitkGammaIndex clitkCommon)
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGammaIndex)
@@ -134,12 +149,12 @@ IF (CLITK_BUILD_TOOLS)
 
   WRAP_GGO(clitkUnsharpMask_GGO_C clitkUnsharpMask.ggo)
   ADD_EXECUTABLE(clitkUnsharpMask clitkUnsharpMask.cxx ${clitkUnsharpMask_GGO_C})
-  TARGET_LINK_LIBRARIES(clitkUnsharpMask clitkCommon ) 
+  TARGET_LINK_LIBRARIES(clitkUnsharpMask clitkCommon )
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkUnsharpMask)
 
   WRAP_GGO(clitkFooImage_GGO_C clitkFooImage.ggo)
   ADD_EXECUTABLE(clitkFooImage clitkFooImage.cxx ${clitkFooImage_GGO_C})
-  TARGET_LINK_LIBRARIES(clitkFooImage clitkCommon ) 
+  TARGET_LINK_LIBRARIES(clitkFooImage clitkCommon )
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkFooImage)
 
   #WRAP_GGO(clitkMedianImageFilter_GGO_C clitkMedianImageFilter.ggo)
@@ -195,7 +210,7 @@ IF (CLITK_BUILD_TOOLS)
   # ADD_EXECUTABLE(clitkExtractSlice clitkExtractSlice.cxx clitkExtractSliceGenericFilter.cxx ${clitkExtractSlice_GGO_C})
   # TARGET_LINK_LIBRARIES(clitkExtractSlice clitkCommon)
   #SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkExtractSlice)
-  
+
   WRAP_GGO(clitkFlipImage_GGO_C clitkFlipImage.ggo)
   ADD_EXECUTABLE(clitkFlipImage clitkFlipImage.cxx clitkFlipImageGenericFilter.cxx ${clitkFlipImage_GGO_C})
   TARGET_LINK_LIBRARIES(clitkFlipImage clitkCommon)
@@ -240,6 +255,11 @@ IF (CLITK_BUILD_TOOLS)
   TARGET_LINK_LIBRARIES(clitkTransformLandmarks clitkCommon)
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkTransformLandmarks)
 
+  WRAP_GGO(clitkDice_GGO_C clitkDice.ggo)
+  ADD_EXECUTABLE(clitkDice clitkDice.cxx ${clitkDice_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkDice clitkSegmentationGgoLib clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDice)
+
   WRAP_GGO(clitkMaskLandmarks_GGO_C clitkMaskLandmarks.ggo)
   ADD_EXECUTABLE(clitkMaskLandmarks clitkMaskLandmarks.cxx ${clitkMaskLandmarks_GGO_C})
   TARGET_LINK_LIBRARIES(clitkMaskLandmarks clitkCommon)
@@ -249,7 +269,7 @@ IF (CLITK_BUILD_TOOLS)
   ADD_EXECUTABLE(clitkJacobianImage clitkJacobianImage.cxx clitkJacobianImageGenericFilter.cxx ${clitkJacobianImage_GGO_C})
   TARGET_LINK_LIBRARIES(clitkJacobianImage clitkCommon)
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkJacobianImage)
-  
+
   WRAP_GGO(clitkPadImage_GGO_C clitkPadImage.ggo)
   ADD_EXECUTABLE(clitkPadImage clitkPadImage.cxx clitkPadImageGenericFilter.cxx ${clitkPadImage_GGO_C})
   TARGET_LINK_LIBRARIES(clitkPadImage clitkCommon)
@@ -262,18 +282,49 @@ IF (CLITK_BUILD_TOOLS)
 
   WRAP_GGO(clitkAnisotropicDiffusion_GGO_C clitkAnisotropicDiffusion.ggo)
   ADD_EXECUTABLE(clitkAnisotropicDiffusion clitkAnisotropicDiffusion.cxx
-                                           clitkAnisotropicDiffusionGenericFilter.cxx
-                                           ${clitkAnisotropicDiffusion_GGO_C})
+    clitkAnisotropicDiffusionGenericFilter.cxx
+    ${clitkAnisotropicDiffusion_GGO_C})
   TARGET_LINK_LIBRARIES(clitkAnisotropicDiffusion clitkCommon)
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkAnisotropicDiffusion)
 
   WRAP_GGO(clitkChangeImageInfo_GGO_C clitkChangeImageInfo.ggo)
   ADD_EXECUTABLE(clitkChangeImageInfo clitkChangeImageInfo.cxx
-                                      clitkChangeImageInfoGenericFilter.cxx
-                                      ${clitkChangeImageInfo_GGO_C})
+    clitkChangeImageInfoGenericFilter.cxx
+    ${clitkChangeImageInfo_GGO_C})
   TARGET_LINK_LIBRARIES(clitkChangeImageInfo clitkCommon)
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkChangeImageInfo)
 
+  WRAP_GGO(clitkMergeAsciiDoseActor_GGO_C clitkMergeAsciiDoseActor.ggo)
+  ADD_EXECUTABLE(clitkMergeAsciiDoseActor clitkMergeAsciiDoseActor.cxx ${clitkMergeAsciiDoseActor_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMergeAsciiDoseActor ITKCommon clitkCommon)
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMergeAsciiDoseActor)
+
+  WRAP_GGO(clitkImageUncertainty_GGO_C clitkImageUncertainty.ggo)
+  ADD_EXECUTABLE(clitkImageUncertainty clitkImageUncertainty.cxx clitkImageUncertainty_ggo.c)
+  TARGET_LINK_LIBRARIES(clitkImageUncertainty clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageUncertainty)
+
+  #=========================================================
+  option(CLITK_USE_ROOT "Build experimental tools using root" OFF)
+  if (CLITK_USE_ROOT)
+    FIND_PACKAGE(ROOT REQUIRED)
+    if(ROOT_FOUND)
+      MESSAGE(STATUS "ROOT found : ${ROOT_LIBRARY_DIR} ${ROOT_INCLUDE_DIR} ${ROOT_LIBRARIES}")
+    ELSE(ROOT_FOUND)
+      MESSAGE(FATAL_ERROR
+        "Cannot build without ROOT.  Please set ROOTSYS environement variable.")
+    endif(ROOT_FOUND)
+    INCLUDE_DIRECTORIES(${ROOT_INCLUDE_DIR})
+    LINK_DIRECTORIES(${ROOT_LIBRARY_DIR})
+    WRAP_GGO(clitkMergeRootFiles_GGO_C clitkMergeRootFiles.ggo)
+    ADD_EXECUTABLE(clitkMergeRootFiles clitkMergeRootFiles.cxx GateMergeManager.cc ${clitkMergeRootFiles_GGO_C})
+    TARGET_LINK_LIBRARIES(clitkMergeRootFiles ${ROOT_LIBRARIES})
+    SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMergeRootFiles)
+  endif()
+  #=========================================================
+
+
+  #=========================================================
   IF(CLITK_EXPERIMENTAL)
     WRAP_GGO(clitkBinaryImageToMesh_GGO_C clitkBinaryImageToMesh.ggo)
     ADD_EXECUTABLE(clitkBinaryImageToMesh clitkBinaryImageToMesh.cxx ${clitkBinaryImageToMesh_GGO_C})
@@ -290,7 +341,10 @@ IF (CLITK_BUILD_TOOLS)
     TARGET_LINK_LIBRARIES(clitkMeshViewer clitkCommon)
     SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMeshViewer)
   ENDIF(CLITK_EXPERIMENTAL)
+  #=========================================================
+
 
+  #=========================================================
   IF(ITK_VERSION_MAJOR VERSION_LESS 4)
     MESSAGE("clitkDicomRTPlan2Gate is not compatible with GDCM<2 (ITK<4). It will not be built.")
   ELSE(ITK_VERSION_MAJOR VERSION_LESS 4)
@@ -299,8 +353,9 @@ IF (CLITK_BUILD_TOOLS)
     TARGET_LINK_LIBRARIES(clitkDicomRTPlan2Gate clitkCommon)
     SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicomRTPlan2Gate)
   ENDIF(ITK_VERSION_MAJOR VERSION_LESS 4)
+  #=========================================================
+
 
   INSTALL (TARGETS ${TOOLS_INSTALL} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
 
 ENDIF(CLITK_BUILD_TOOLS)
-
diff --git a/tools/GateMergeManager.cc b/tools/GateMergeManager.cc
new file mode 100644 (file)
index 0000000..5c5a12c
--- /dev/null
@@ -0,0 +1,766 @@
+/*----------------------
+   GATE version name: gate_v...
+
+   Copyright (C): OpenGATE Collaboration
+
+This software is distributed under the terms
+of the GNU Lesser General  Public Licence (LGPL)
+See GATE/LICENSE.txt for further details
+----------------------*/
+
+
+#include <TROOT.h>
+#include <TFile.h>
+#include <TChain.h>
+#include <TTree.h>
+#include <TBranch.h>
+#include <TIterator.h>
+#include <TObject.h>
+#include <TKey.h>
+#include <TH1.h>
+#include <TH2.h>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <glob.h>
+#include <ctype.h>
+#include <sstream>
+#include <vector>
+#include <cstdlib>
+#include <cmath>
+#include <list>
+
+#include "GateMergeManager.hh"
+
+using namespace std;
+
+void GateMergeManager::StartMerging(string splitfileName){
+
+  // get the files to merge
+  ReadSplitFile(splitfileName);
+  //do the merging
+  if (m_fastMerge==true) FastMergeRoot();
+  else MergeRoot();
+
+  //if we are here the merging has been successful
+  //we mark the directory as ready for cleanup
+  //string dir   = splitfileName.substr(0,splitfileName.rfind("/"));
+  //string ready = "touch "+dir+"/ready_for_delete";
+  //const int res=system(ready.c_str());
+  //if(res) cout<<"Strange?? Can't mark "<<dir<<" as done!"<<endl;
+};
+
+void GateMergeManager::StartMergingFromFilenames(Strings filenames, string outputfile)
+{
+       for (Strings::const_iterator iter=filenames.begin(); iter!=filenames.end(); iter++)
+       {
+               m_vRootFileNames.push_back(*iter);
+               if(m_verboseLevel>2) cout<<"Root input file name: "<<m_vRootFileNames.back()<<endl;
+       }
+
+       m_Nfiles = m_vRootFileNames.size();
+       m_RootTargetName=m_outDir+outputfile;
+       if(m_verboseLevel>2) cout<<"Root output file name: "<<m_RootTargetName<<endl;
+
+       if (m_fastMerge==true) FastMergeRoot();
+       else MergeRoot();
+};
+
+// to process the splitfile
+void GateMergeManager::ReadSplitFile(string splitfileName){
+
+  ifstream splitfile;
+  splitfile.open(splitfileName.c_str());
+  if(!splitfile){
+     cout<<"Can't open split file: "<<splitfileName<<endl;
+     exit(0);
+  };
+
+  //avoid multiple calls
+  if(m_vRootFileNames.size()>0) return;
+
+  stringstream ssnfiles;
+  char cline[512];
+  while(splitfile){               //we allow for rubbish before "Number of files:"
+     splitfile.getline(cline,512);
+     if(!strncmp(cline,"Number of files:",16)){
+         ssnfiles.str(cline+16);
+         ssnfiles>>m_Nfiles;      // the number of files to merge
+         break;
+     }
+  }
+
+  // now we look for the file names
+  int iRoot=0;
+  while(splitfile){
+     splitfile.getline(cline,512);
+     // check for root
+     // input files
+     if(!strncmp(cline,"Root filename:",14)){
+        m_vRootFileNames.push_back(strtok(cline+15," "));
+        m_vRootFileNames[iRoot]+=".root";
+        if(m_verboseLevel>2) cout<<"Root input file name: "<<m_vRootFileNames[iRoot]<<endl;
+        iRoot++;
+     }
+     // output file
+     else if(!strncmp(cline,"Original Root filename:",23)){
+        m_RootTargetName=strtok(cline+23," ");
+        m_RootTargetName+=".root";
+        if(m_outDir!=""){// output directory option used
+           //replace path with outDir
+           size_t pos=m_RootTargetName.rfind('/',m_RootTargetName.length());
+           if(pos==string::npos) pos=-1;
+           m_RootTargetName=m_outDir+m_RootTargetName.substr(pos+1);
+        }
+        if(m_verboseLevel>2) cout<<"Root output file name: "<<m_RootTargetName<<endl;
+     }
+  }
+
+  // check if number of root files correct
+  if(iRoot && iRoot!=m_Nfiles) {
+       cout<<"Inconsistent number of root file entries in split file!"<<endl;
+       exit(0);
+  }
+}
+
+/************************************************************************************/
+void GateMergeManager::FastMergeRoot()
+{
+   //check target name
+   if(m_RootTargetName=="") {
+      cout<<"No root output file name given in split file"<<endl;
+      exit(0);
+   }
+
+   // number of files to merge
+   int nfiles=m_vRootFileNames.size();
+   if(nfiles<1){
+      cout<<"No files to merge!"<<endl;
+      exit(0);
+   }
+   //we try to recover the last_event_ID in all root files
+   for(int i=0;i<nfiles;i++) {
+      filearr.push_back(TFile::Open(m_vRootFileNames[i].c_str(),"OLD"));
+      if(filearr[i]==NULL){
+         cout<<"Not a readable file "<<m_vRootFileNames[i]<<" - exit!"<<endl;   
+         exit(0);
+      }
+   }  
+   m_lastEvents.resize(nfiles+1);
+   m_lastEvents[0]=0;
+   bool flgLstEvntID(false);
+
+   // latest_event_ID histogram
+   flgLstEvntID=true;
+   TH1* h=NULL;
+   for(int i=0;i<nfiles;i++){
+     h = (TH1*)filearr[i]->Get("latest_event_ID");
+     m_lastEvents[i+1]=int(h->GetMean());
+     }
+
+   if(!flgLstEvntID) {
+      cout<<"FastMerge: No latest_event_ID histogram - exit!"<<endl;
+      exit(0);
+   }
+
+ /*for (int i=0;i<nfiles;i++)
+  {
+   cout<<"Last ID is: "<<m_lastEvents[i+1]<<" File " <<i+1<<endl;
+  }*/
+
+   //find all trees
+   vector<string> treeNames;
+   TFile* node = TFile::Open(m_vRootFileNames[0].c_str(),"OLD");
+   TIter nextkey(node->GetListOfKeys());
+   TKey *key=0;
+   while ((key = (TKey*)nextkey()))
+   {
+     node->cd();
+     TObject* obj = (TObject*)key->ReadObj();
+     if(  obj->IsA()->InheritsFrom("TTree"))
+     {
+       //no doubles
+       bool singleName=true;
+       for(unsigned int i=0;i<treeNames.size();i++)
+       {
+         if(treeNames[i].compare(obj->GetName())==0)
+         {
+           singleName=false;
+           break;
+         }
+       }
+       if(singleName) treeNames.push_back(obj->GetName());
+     }
+   }
+   //take care of all trees
+   for(unsigned int i=0;i<treeNames.size();i++) 
+   {
+     if(!MergeTree(treeNames[i])) if(m_verboseLevel>1) cout<<"Problem with merging "<<treeNames[i]<<endl; 
+   }
+}
+/************************************************************************************/
+void GateMergeManager::MergeRoot(){
+
+   //check target name
+   if(m_RootTargetName=="") {
+      cout<<"No root output file name given in split file"<<endl;
+      exit(0);
+   }
+
+   // number of files to merge
+   int nfiles=m_vRootFileNames.size();
+
+   // the root output file
+   if(m_forced) {
+      m_RootTarget = TFile::Open(m_RootTargetName.c_str(),"RECREATE");
+   } else {
+      m_RootTarget = TFile::Open(m_RootTargetName.c_str(),"NEW");
+      if(!m_RootTarget){
+          cout<<"The root ouput file already exists! Try -f to overwrite and erase the file."<<endl;
+          exit(0);
+      }
+   }
+
+   if(nfiles<1){
+      cout<<"No files to merge!"<<endl;
+      exit(0);
+   }
+
+   TFile* filearr[nfiles];
+   for(int i=1;i<nfiles;i++) {
+      filearr[i] = TFile::Open(m_vRootFileNames[i].c_str(),"OLD");
+      if(filearr[i]==NULL){
+         cout<<"Not a readable file "<<m_vRootFileNames[i]<<" - exit!"<<endl;   
+         exit(0);
+      }
+   }
+
+// first we copy all histos (only top directory) 
+// and look for the latestEventID
+// and find out which  trees/ntuples  exist
+   m_lastEvents.resize(nfiles+1);
+       m_lastEvents[0]=0;
+
+   bool flgLstEvntID(false);
+
+   if(m_verboseLevel>0) {
+      cout<<"Combining: ";
+      for(int i=0;i<nfiles;i++) cout<<m_vRootFileNames[i]<<" ";
+      cout<<"-> "<<m_RootTarget->GetName()<<endl;
+   }
+
+   vector<string> treeNames;
+   TFile* node = TFile::Open(m_vRootFileNames[0].c_str(),"OLD");
+   if(node==NULL){
+       cout<<"Not a readable file "<<m_vRootFileNames[0]<<" - exit!"<<endl;   
+       exit(0);
+   }
+        TIter nextkey(node->GetListOfKeys());
+        TKey *key=0;
+        while ((key = (TKey*)nextkey())) {
+          node->cd();
+          TObject* obj = (TObject*)key->ReadObj();
+          if(  obj->IsA()->InheritsFrom("TH1")){
+             m_RootTarget->cd();
+             TH1 *h1 = (TH1 *)obj->Clone();
+             if(strcmp(h1->GetName(),"latest_event_ID")){
+                     //any other histogram
+                     for(int i=1;i<nfiles;i++){
+                          TH1 *h2 = (TH1*)filearr[i]->Get( h1->GetName() );
+                          h1->Add( h2 ); 
+                     }
+                     h1->Write();
+             } else {
+                          // latest_event_ID histogram
+                          flgLstEvntID=true;
+                          m_lastEvents[1]=int(h1->GetMean());
+                          TH1* h=NULL;
+                          for(int i=1;i<nfiles;i++){
+                                  h = (TH1*)filearr[i]->Get("latest_event_ID");
+                                  m_lastEvents[i+1]=int(h->GetMean());
+                          }
+                          if(h!=NULL) h->Write(); // we keep the highest latest_event_ID to allow for successive merging
+                          else h1->Write();
+              }
+         }
+         if(  obj->IsA()->InheritsFrom("TH2")){
+           m_RootTarget->cd();
+           TH2 *h1 = (TH2 *)obj->Clone();
+                        for(int i=1;i<nfiles;i++){
+                                TH2 *h2 = (TH2*)filearr[i]->Get( h1->GetName() );
+                                h1->Add( h2 ); 
+                        }
+                        h1->Write();
+                }
+         if(  obj->IsA()->InheritsFrom("TTree")){
+           //no doubles
+           bool singleName=true;
+           for(unsigned int i=0;i<treeNames.size();i++) {
+              if(treeNames[i].compare(obj->GetName())==0){
+                 singleName=false;
+                 break;
+              }
+           }
+           if(singleName) treeNames.push_back(obj->GetName());
+         }
+   }
+   if(!flgLstEvntID) {
+      cout<<"Merge: No latest_event_ID histogram - exit!"<<endl;
+      exit(0);
+   }
+
+   //now we take care of the trees
+   for(unsigned int i=0;i<treeNames.size();i++) 
+     if(!MergeTree(treeNames[i])) if(m_verboseLevel>1) cout<<"Problem with merging "<<treeNames[i]<<endl; 
+
+   // everything is done
+};
+
+/*******************************************************************************************/
+// cleanup after merging
+void GateMergeManager::StartCleaning(string splitfileName,bool test){
+
+  // get the files to erase
+  ReadSplitFile(splitfileName);
+
+  string dir=splitfileName.substr(0,splitfileName.rfind("/"));
+
+  // test for the mark: ready_for_delete 
+  string touched=dir+"/ready_for_delete";
+  ifstream ready;
+  ready.open(touched.c_str());
+  if (!ready) {
+     cout<<"Cannot do the cleanup - directory "<<dir<<" not marked as ready!"<<endl;
+     if(!test) exit(0);
+  }
+
+  // print info
+  if(test)                    cout<<"I would like to erase:"<<endl;
+  if(!test&&m_verboseLevel>1) cout<<"Going to erase the following files:"<<endl;
+  if(m_verboseLevel>1||test){
+     cout<<" --> "<<dir<<endl;
+     // root
+     for(unsigned int i=0;i<m_vRootFileNames.size();i++){
+        cout<<" --> "<<m_vRootFileNames[i]<<endl;
+     }
+  }
+
+  // erase!
+  if(!test){
+     for(unsigned int i=0;i<m_vRootFileNames.size();i++){
+        const string rmfiles("rm -f "+m_vRootFileNames[i]);
+        const int res = system(rmfiles.c_str());
+        if(res) {
+               cout<<"Could not remove "<<m_vRootFileNames[i]<<endl;
+               cout<<"Please remove it manually!"<<endl;
+        }
+     }
+     const string rmfiles("rm -f "+dir+"/*");
+     system(rmfiles.c_str());
+     const string rmdir="rm -f -r "+dir;
+     const int res2 = system(rmdir.c_str());
+     if(res2) {
+            cout<<"Could not remove "<<dir<<endl;
+            cout<<"Please remove it manually!"<<endl;
+     }
+  }
+}
+
+/*******************************************************************************************/
+//find out what kind of tree we have and call the right merger
+bool GateMergeManager::MergeTree(string chainName){
+if (m_fastMerge==false)
+ {
+   TChain* chain = new TChain(chainName.c_str());
+
+   // number of files to merge
+   int nfiles=m_vRootFileNames.size();
+
+   for(int i=0;i<nfiles;i++) chain->Add(m_vRootFileNames[i].c_str());
+   int nentries=chain->GetEntries();
+   if(nentries<=0) {
+      if(m_verboseLevel>1) cout<<chain->GetName()<<" is empty!"<<endl;
+      return false;
+   }
+
+   if(chainName=="Gate") MergeGate(chain);
+
+   if(chain->FindBranch("eventID1")!=NULL) {
+     if(  (chain->FindBranch("runID")==NULL)
+        ||(chain->FindBranch("time1")==NULL) 
+        ||(chain->FindBranch("time2")==NULL) ) {
+        cout<<"Cannot find one of:  runID, time1, time2 in "<<chain->GetName()<<endl;
+        return false;
+     }
+     // coincidence
+     return MergeCoin(chain);
+
+   } else if(  (chain->FindBranch("runID")==NULL)||(chain->FindBranch("eventID")==NULL)
+                                                  ||(chain->FindBranch("time")==NULL) )
+            {
+             cout<<"Cannot find one of: runID, eventID, time in "<<chain->GetName()<<endl;
+             return false;
+            }
+           // Singles or Hits
+           return MergeSing(chain);
+   }
+   else
+   {
+     if (chainName.find("Hits",0)!=string::npos) return FastMergeSing(chainName);
+     if (chainName.find("Singles",0)!=string::npos) return FastMergeSing(chainName);
+     if (chainName.find("Gate",0)!=string::npos) return FastMergeGate(chainName);
+     if (chainName.find("Coincidences",0)!=string::npos) return FastMergeCoin(chainName);
+   }
+   return 0;
+}
+
+/*******************************************************************************************/
+bool GateMergeManager::FastMergeGate(string name)
+{
+//create the output file
+float   event   = 0;
+int offset      = 0;
+int currentfile = 0;
+float lastEvent =-1;
+//float maxtime   =-999999999;
+string clusterName=name+"_cluster";
+
+for(int j=0;j<m_Nfiles;j++)
+ {
+   filearr[j]->ReOpen("UPDATE");
+   TTree *oldTree = (TTree*)gDirectory->Get(name.c_str());
+   TBranch *branch  = oldTree->GetBranch("event");
+   branch->SetAddress(&event);
+   TBranch* newBranch=oldTree->Branch("eventcluster",&event,"event");
+
+   Int_t nentries=(Int_t)oldTree->GetEntries();
+
+   if (j==0) offset=0;
+   else offset+=m_lastEvents[currentfile];
+   currentfile++;
+
+   for(int i=0;i<nentries;i++)
+      {
+       branch->GetEvent(i);
+       if(lastEvent!=event)
+        {
+         lastEvent=event;
+         event+=offset;
+         newBranch->Fill();
+        } 
+       else
+        {
+         if((i==nentries-1) && (j==m_Nfiles-1))
+          {
+           event+=offset;
+           newBranch->Fill();
+          }
+         else if (i!=nentries-1) 
+              { 
+               branch->GetEvent(i);
+               event+=offset;
+               newBranch->Fill();
+               lastEvent=0;
+               offset=0;
+              }
+        }
+      }
+    oldTree->Write();
+ }
+ return true;
+}
+
+/*******************************************************************************************/
+bool GateMergeManager::FastMergeSing(string name)
+{
+int eventID = 0;
+int runID = 0; 
+int offset      = 0;
+int currentfile = 0;
+float lastRun =-1;
+string clusterName=name+"_cluster"; 
+
+for(int j=0;j<m_Nfiles;j++)
+ {
+   filearr[j]->ReOpen("UPDATE");
+   TTree *oldTree = (TTree*)gDirectory->Get(name.c_str());
+   TBranch *branch  = oldTree->GetBranch("eventID");
+   branch->SetAddress(&eventID);
+   TBranch *branch2  = oldTree->GetBranch("runID");
+   branch2->SetAddress(&runID);
+   TBranch* newBranch=oldTree->Branch("eventIDcluster",&eventID,"eventID/I");
+
+   Int_t nentries=(Int_t)oldTree->GetEntries();
+
+   if (j==0) offset=0;
+   else offset+=m_lastEvents[currentfile];
+   currentfile++;
+
+   for(int i=0;i<nentries;i++)
+     {
+      branch->GetEvent(i);
+      if(lastRun!=runID)
+        {
+         lastRun=runID;
+         offset=0;
+        }
+      eventID+=offset;
+      newBranch->Fill();
+    }
+  oldTree->Write();
+  }
+  return true;
+}
+
+/*******************************************************************************************/
+bool GateMergeManager::FastMergeCoin(string name)
+{
+//create the output file
+int eventID1 = 0;
+int eventID2 = 0;
+int runID = 0;
+int offset      = 0;
+int currentfile = 0;
+float lastRun =-1;
+string clusterName=name+"_cluster";
+cout<<"starting coincidence merging..."<<endl;
+for(int j=0;j<m_Nfiles;j++)
+ {
+cout<<"working on file..."<<j<<endl;
+   filearr[j]->ReOpen("UPDATE");
+   TTree *oldTree = (TTree*)gDirectory->Get(name.c_str());
+   TBranch *branch1  = oldTree->GetBranch("eventID1");
+   branch1->SetAddress(&eventID1);
+   TBranch *branch2  = oldTree->GetBranch("eventID2");
+   branch2->SetAddress(&eventID2);
+   TBranch *branch3  = oldTree->GetBranch("runID");
+   branch3->SetAddress(&runID);
+
+   TBranch* newBranch1=oldTree->Branch("eventID1cluster",&eventID1,"eventID1/I");
+   TBranch* newBranch2=oldTree->Branch("eventID2cluster",&eventID2,"eventID2/I");
+
+   Int_t nentries=(Int_t)oldTree->GetEntries();
+
+   if (j==0) offset=0;
+   else offset+=m_lastEvents[currentfile];
+   cout<<"the offset in this file is: "<<offset<<endl;
+   currentfile++;
+
+   for(int i=0;i<nentries;i++){
+       branch1->GetEvent(i);
+       branch2->GetEvent(i);
+       branch3->GetEvent(i);
+       if(lastRun!=runID) 
+        {
+         lastRun=runID;
+         offset=0; 
+        }
+       eventID1+=offset;
+       eventID2+=offset;
+       newBranch1->Fill();
+       newBranch2->Fill();
+    }
+    oldTree->Write();
+ }
+    return true;
+}
+
+/*******************************************************************************************/
+// Gate tree merger
+bool GateMergeManager::MergeGate(TChain* chainG) {
+
+   int nentries=chainG->GetEntries();   
+
+   float   event   = 0;
+   chainG->SetBranchAddress("event",&event);
+   Float_t iontime = 0;
+   chainG->SetBranchAddress("iontime",&iontime);
+
+   //create the new tree
+   //Allow for large files and do not write every bit separately
+   m_RootTarget->cd();
+   TTree * newTree = chainG->CloneTree(0);
+   newTree->SetAutoSave(2000000000);
+   if(m_maxRoot!=0) newTree->SetMaxTreeSize(m_maxRoot);
+   else newTree->SetMaxTreeSize(17179869184LL);
+
+   // changing the compression level everywhere
+   TBranch *br;
+   TIter next(newTree->GetListOfBranches());
+   while ((br=(TBranch*)next())) br->SetCompressionLevel(m_CompLevel);
+
+   // the main part: modify the eventID
+   int offset      = 0;
+   int currentTree = 0;
+   float lastEvent =-1;
+   float maxtime   =-999999999;
+   for(int i=0;i<nentries;i++){
+       if (chainG->GetEntry(i) <= 0) break; //end of chain
+       if(chainG->GetTreeNumber()>currentTree) {
+           currentTree++;
+           offset+=m_lastEvents[currentTree];
+           // check for overlaping time intervalls between different files
+           // (not within the same file i.e. no time order assumed)
+           if(iontime<maxtime)
+              if(m_verboseLevel>0) 
+                 cout<<"Warning - overlapping Gate iontime ("
+                     <<iontime<<") in file: "<<m_vRootFileNames[currentTree].c_str()<<endl;
+       }
+       // run end is marked by repeating event
+       if(lastEvent!=event) {
+           lastEvent=event;
+//           if (fpclassify(iontime)!=FP_NAN && fpclassify(iontime)!=FP_INFINITE) {
+           if(finite(iontime)){
+             if(maxtime<iontime) maxtime=iontime;
+             // the offset to get a unique event numbering
+             event+=offset;
+             newTree->Fill();
+           } else {
+             cout<<"Warning - inf or NaN in Gate tree for iontime! "<<m_vRootFileNames[currentTree].c_str()<<endl;
+             //we are lost anyhow
+             maxtime   =-999999999;
+           }
+        } else {
+           // run end 
+           if(chainG->GetEntry(i+1) <= 0)  {              //chain end fill the double event 
+              event+=offset;
+              newTree->Fill();
+           } else if(chainG->GetTreeNumber()==currentTree             //no new file or
+                    ||(chainG->GetTreeNumber()>currentTree
+                       &&m_lastEvents[chainG->GetTreeNumber()]==0) ) { //new file with no offset fill double event
+              chainG->GetEntry(i);
+              event+=offset;
+              newTree->Fill();
+              lastEvent=0;// we may have triple 1 (1 event run)
+              offset=0;
+           }
+        }
+      }
+      newTree->Write();
+      delete newTree;
+      return true;
+}
+
+/*******************************************************************************************/
+// Singles and Hits tree merger
+bool GateMergeManager::MergeSing(TChain* chainS){
+
+   int nentriesS=chainS->GetEntries();
+
+   int eventID = 0;
+   int runID   = 0;
+   double time = 0;
+
+   chainS->SetBranchAddress("eventID",&eventID);
+   chainS->SetBranchAddress("runID",&runID);
+   chainS->SetBranchAddress("time",&time);
+
+   m_RootTarget->cd();
+   TTree * newSing = chainS->CloneTree(0);
+   newSing->SetAutoSave(2000000000);
+   if(m_maxRoot!=0) newSing->SetMaxTreeSize(m_maxRoot);
+   else newSing->SetMaxTreeSize(17179869184LL);
+
+   // changing CompLevel everywhere
+   TBranch *br;
+   TIter next(newSing->GetListOfBranches());
+   while ((br=(TBranch*)next())) br->SetCompressionLevel(m_CompLevel);
+
+   //the main part: changing eventID
+   int offset      = 0;
+   int currentTree = 0;
+   float lastRun   = 0;
+   float maxtime   =-999999999;
+   for(int i=0;i<nentriesS;i++){
+         if(chainS->GetEntry(i) <= 0) break; //end of chain
+         if(chainS->GetTreeNumber()>currentTree) {
+           currentTree++;
+            offset+=m_lastEvents[currentTree];
+           // check for overlaping time intervalls between different files
+           // (not within the same file i.e. no time order assumed)
+           if(time<maxtime) 
+               if(m_verboseLevel>0) 
+                  cout<<"Warning - overlapping Singles time ("
+                      <<time<<") in file: "<<m_vRootFileNames[currentTree].c_str()<<endl;
+         }
+         // the offset to get a unique event numbering
+         if(lastRun!=runID) {
+            // run end 
+            lastRun=runID;
+            offset=0;     //new run in file we must not change the eventID anymore
+         }
+         eventID+=offset;
+         newSing->Fill();
+         if(maxtime<time)maxtime=time;
+    }
+    newSing->Write();
+    delete newSing;
+    return true;
+};
+
+/*******************************************************************************************/
+// Coincidences tree merger
+bool GateMergeManager::MergeCoin(TChain* chainC){
+
+   int nentriesC=chainC->GetEntries();
+
+    int eventID1 = 0;
+    chainC->SetBranchAddress("eventID1",&eventID1);
+    double time1 = 0;
+    chainC->SetBranchAddress("time1",&time1);
+    int eventID2 = 0;
+    chainC->SetBranchAddress("eventID2",&eventID2);
+    double time2 = 0;
+    chainC->SetBranchAddress("time2",&time2);
+    int runID    = 0;
+    chainC->SetBranchAddress("runID",&runID);
+
+    m_RootTarget->cd();
+    TTree * newCoin = chainC->CloneTree(0);
+    newCoin->SetAutoSave(2000000000);
+    if(m_maxRoot!=0) newCoin->SetMaxTreeSize(m_maxRoot);
+    else newCoin->SetMaxTreeSize(17179869184LL);
+
+    // changing CompLevel everywhere
+    TBranch *br;
+    TIter next(newCoin->GetListOfBranches());
+    while ((br=(TBranch*)next())) br->SetCompressionLevel(m_CompLevel);
+
+    int offset      = 0;
+    int currentTree = 0;
+    float lastRun   = 0;
+    float maxtime   =-999999999;
+    for(int i=0;i<nentriesC;i++){
+       if(chainC->GetEntry(i) <= 0) break; //end of chain
+       if(chainC->GetTreeNumber()>currentTree) {
+         currentTree++;
+         offset+=m_lastEvents[currentTree];
+         // check for overlaping time intervalls between different files
+         // (not within the same file i.e. no time order assumed)
+         if(time1<maxtime) 
+           if(m_verboseLevel>0)
+               cout<<"Warning - overlapping Coincidences time1 ("
+                   <<time1<<") in file: "<<m_vRootFileNames[currentTree].c_str()<<endl;
+         if(time2<maxtime) 
+           if(m_verboseLevel>0)
+               cout<<"Warning - overlapping Coincidences time2 ("
+                   <<time2<<") in file: "<<m_vRootFileNames[currentTree].c_str()<<endl;
+       }
+       // the offset to get a unique event numbering
+       if(lastRun!=runID) {
+          // run end
+          lastRun=runID;
+          offset=0; //new run in file we must not change the eventID anymore
+       }
+       eventID1+=offset;
+       eventID2+=offset;
+       newCoin->Fill();
+       if(maxtime<time1)maxtime=time1;
+       if(maxtime<time2)maxtime=time2;
+    }
+    newCoin->Write();
+    delete newCoin;
+    return true;
+}
+/*******************************************************************************************/
diff --git a/tools/GateMergeManager.hh b/tools/GateMergeManager.hh
new file mode 100644 (file)
index 0000000..126dea3
--- /dev/null
@@ -0,0 +1,81 @@
+/*----------------------
+   GATE version name: gate_v...
+
+   Copyright (C): OpenGATE Collaboration
+
+This software is distributed under the terms
+of the GNU Lesser General  Public Licence (LGPL)
+See GATE/LICENSE.txt for further details
+----------------------*/
+
+
+#ifndef GateMergeManager_h
+#define GateMergeManager_h 1
+#include <iostream>
+#include <string>
+#include <vector>
+#include <TFile.h>
+#include <TChain.h>
+#include <cstdlib>
+#include <list>
+
+using namespace std;
+typedef list<string> Strings;
+
+class GateMergeManager
+{
+public:
+
+  GateMergeManager(bool fastMerge,int verboseLevel,bool forced,Long64_t maxRoot,string outDir){
+     m_verboseLevel = verboseLevel;
+     m_forced       =       forced;
+     m_maxRoot      =      maxRoot;
+     m_outDir       =       outDir;
+     m_CompLevel    =            1;
+     m_fastMerge    =    fastMerge;
+  };
+  ~GateMergeManager()
+  {
+         for (std::vector<TFile*>::const_iterator iter=filearr.begin(); iter!=filearr.end(); iter++)
+         {
+                 (*iter)->Close();
+                 delete *iter;
+         }
+  }
+
+
+  void StartMerging(string splitfileName);
+  void StartMergingFromFilenames(Strings filenames, string outputfile);
+  void ReadSplitFile(string splitfileName);
+  bool MergeTree(string name);
+  bool MergeGate(TChain* chain);
+  bool MergeSing(TChain* chain);
+  bool MergeCoin(TChain* chain);
+
+  // the cleanup after succesful merging
+  void StartCleaning(string splitfileName,bool test);
+
+  // the merging methods
+  void MergeRoot();
+
+private:
+  void FastMergeRoot(); 
+  bool FastMergeGate(string name);
+  bool FastMergeSing(string name);
+  bool FastMergeCoin(string name); 
+  bool           m_forced;             // if to overwrite existing files
+  int      m_verboseLevel;  
+  std::vector<TFile*>         filearr;
+  Long64_t      m_maxRoot;             // maximum size of root output file
+  int         m_CompLevel;             // compression level for root output
+  string         m_outDir;             // where to save the output files
+  int            m_Nfiles;             // number of files to mergw
+  vector<int> m_lastEvents;            // latestevent from al files
+  vector<string> m_vRootFileNames;     // names of root files to merge
+  TFile*         m_RootTarget;         // root output file
+  string         m_RootTargetName;     // name of target i.e. root output file
+  bool           m_fastMerge;          // fast merge option, corrects the eventIDs locally
+};
+
+
+#endif
index 39506326f572a2bb614da44524c64547879eda41..613e1cc677b868305c2cf5e5513baacb7026751a 100644 (file)
@@ -87,11 +87,6 @@ namespace clitk
     //----------------------------------------  
     void Update();
 
-    template<unsigned int Dimension, class PixelType>
-      static
-      typename itk::Matrix<double, Dimension+1, Dimension+1>
-      createMatrixFromElastixFile(std::vector<std::string> & filename, bool verbose=true);
-
   protected:
 
     //----------------------------------------  
@@ -108,10 +103,6 @@ namespace clitk
     template <unsigned int Dimension, class PixelType>  void UpdateWithDimAndPixelType();
     template <unsigned int Dimension, class PixelType>  void UpdateWithDimAndVectorType();
 
-    static bool GetElastixValueFromTag(std::ifstream & is, std::string tag, std::string & value); 
-    static void GetValuesFromValue(const std::string & s, 
-                                   std::vector<std::string> & values);
-
     //----------------------------------------  
     // Data members
     //----------------------------------------
index 03cf862e2ee261548d6707761648821823b9e1fb..150c8c172187c9455af05d8a7861e05d34c46855 100644 (file)
@@ -22,6 +22,7 @@
 #include <istream>
 #include <iterator>
 #include <itkCenteredEuler3DTransform.h>
+#include "clitkElastix.h"
 
 namespace clitk
 {
@@ -183,7 +184,7 @@ namespace clitk
           if (m_ArgsInfo.elastix_given) {
             std::vector<std::string> s;
             for(uint i=0; i<m_ArgsInfo.elastix_given; i++) s.push_back(m_ArgsInfo.elastix_arg[i]);
-            matrix = createMatrixFromElastixFile<Dimension,PixelType>(s, m_Verbose);
+            matrix = createMatrixFromElastixFile<Dimension>(s, m_Verbose);
           }
           else 
             matrix.SetIdentity();
@@ -491,140 +492,6 @@ namespace clitk
 
   }
   //-------------------------------------------------------------------
-  
-  
-  //-------------------------------------------------------------------
-  template<class args_info_type>
-  template<unsigned int Dimension, class PixelType>
-  typename itk::Matrix<double, Dimension+1, Dimension+1>
-                                                           AffineTransformGenericFilter<args_info_type>::createMatrixFromElastixFile(std::vector<std::string> & filename, bool verbose)
-  {
-    if (Dimension != 3) {
-      FATAL("Only 3D yet" << std::endl);
-    }
-    typename itk::Matrix<double, Dimension+1, Dimension+1> matrix;
-
-    itk::CenteredEuler3DTransform<double>::Pointer mat = itk::CenteredEuler3DTransform<double>::New();
-    itk::CenteredEuler3DTransform<double>::Pointer previous;
-    for(uint j=0; j<filename.size(); j++) {
-      
-      // Open file
-      if (verbose) std::cout << "Read elastix parameters in " << filename[j] << std::endl;
-      std::ifstream is;
-      clitk::openFileForReading(is, filename[j]);
-      
-      // Check Transform
-      std::string s; 
-      bool b = GetElastixValueFromTag(is, "Transform ", s);
-      if (!b) {
-        FATAL("Error must read 'Transform' in " << filename[j] << std::endl);
-      }
-      if (s != "EulerTransform") {
-        FATAL("Sorry only 'EulerTransform'" << std::endl);
-      }
-      
-      // FIXME check
-      //    (InitialTransformParametersFilename[j] "NoInitialTransform")
-      
-      // Get CenterOfRotationPoint
-      GetElastixValueFromTag(is, "CenterOfRotationPoint ", s); // space is needed
-      if (!b) {
-        FATAL("Error must read 'CenterOfRotationPoint' in " << filename[j] << std::endl);
-      }
-      std::vector<std::string> cor; 
-      GetValuesFromValue(s, cor);
-      
-      // Get Transformparameters
-      GetElastixValueFromTag(is, "TransformParameters ", s); // space is needed
-      if (!b) {
-        FATAL("Error must read 'TransformParameters' in " << filename[j] << std::endl);
-      }
-      std::vector<std::string> results; 
-      GetValuesFromValue(s, results);
-      
-      // construct a stream from the string
-      itk::CenteredEuler3DTransform<double>::ParametersType p;
-      p.SetSize(9);
-      for(uint i=0; i<3; i++)
-        p[i] = atof(results[i].c_str()); // Rotation
-      for(uint i=0; i<3; i++)
-        p[i+3] = atof(cor[i].c_str()); // Centre of rotation
-      for(uint i=0; i<3; i++)
-        p[i+6] = atof(results[i+3].c_str()); // Translation
-      mat->SetParameters(p);
-    
-      if (verbose) {
-        std::cout << "Rotation      (deg) : " << rad2deg(p[0]) << " " << rad2deg(p[1]) << " " << rad2deg(p[2]) << std::endl;
-        std::cout << "Center of rot (phy) : " << p[3] << " " << p[4] << " " << p[5] << std::endl;
-        std::cout << "Translation   (phy) : " << p[6] << " " << p[7] << " " << p[8] << std::endl;
-      }
-
-      // Compose with previous if needed
-      if (j!=0) {
-        mat->Compose(previous);
-        if (verbose) {
-          std::cout << "Composed rotation      (deg) : " << rad2deg(mat->GetAngleX()) << " " << rad2deg(mat->GetAngleY()) << " " << rad2deg(mat->GetAngleZ()) << std::endl;
-          std::cout << "Composed center of rot (phy) : " << mat->GetCenter() << std::endl;
-          std::cout << "Compsoed translation   (phy) : " << mat->GetTranslation() << std::endl;
-        }
-      }
-      // previous = mat->Clone(); // ITK4
-      previous = itk::CenteredEuler3DTransform<double>::New();
-      previous->SetParameters(mat->GetParameters());
-    }
-
-    mat = previous;
-    for(uint i=0; i<3; i++)
-      for(uint j=0; j<3; j++)
-        matrix[i][j] = mat->GetMatrix()[i][j];
-    // Offset is -Rc + t + c
-    matrix[0][3] = mat->GetOffset()[0];
-    matrix[1][3] = mat->GetOffset()[1];
-    matrix[2][3] = mat->GetOffset()[2];
-    matrix[3][3] = 1;
-    
-    return matrix;
-  }
-
-  //-------------------------------------------------------------------
-  template<class args_info_type>
-  bool
-  AffineTransformGenericFilter<args_info_type>::GetElastixValueFromTag(std::ifstream & is, 
-                                                                       std::string tag, 
-                                                                       std::string & value)
-  {
-    std::string line;
-    is.seekg (0, is.beg);
-    while(std::getline(is, line))   {
-      unsigned pos = line.find(tag);
-      if (pos<line.size()) {
-        value=line.substr(pos+tag.size(),line.size()-2);// remove last ')'
-        value.erase (std::remove (value.begin(), value.end(), '"'), value.end());
-        value.erase (std::remove (value.begin(), value.end(), ')'), value.end());
-        return true;
-      }
-    }
-    return false;
-  }
-  //-------------------------------------------------------------------
-
-
-  //-------------------------------------------------------------------
-  template<class args_info_type>
-  void
-  AffineTransformGenericFilter<args_info_type>::GetValuesFromValue(const std::string & s, 
-                                                                   std::vector<std::string> & values)
-  {
-    std::stringstream strstr(s);
-    std::istream_iterator<std::string> it(strstr);
-    std::istream_iterator<std::string> end;
-    std::vector<std::string> results(it, end);
-    values.clear();
-    values.resize(results.size());
-    for(uint i=0; i<results.size(); i++) values[i] = results[i];
-  }
-  //-------------------------------------------------------------------
-
 
 } //end clitk
 
diff --git a/tools/clitkDice.cxx b/tools/clitkDice.cxx
new file mode 100644 (file)
index 0000000..121bcb4
--- /dev/null
@@ -0,0 +1,47 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+// clitk
+#include "clitkIO.h"
+#include "clitkDice_ggo.h"
+
+#include "clitkLabelImageOverlapMeasureGenericFilter.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+  // Init command line
+  GGO(clitkDice, args_info);
+  CLITK_INIT;
+
+  // Filter
+  typedef clitk::LabelImageOverlapMeasureGenericFilter<args_info_clitkDice> FilterType;
+  FilterType::Pointer filter = FilterType::New();
+
+  filter->SetArgsInfo(args_info);
+
+  try {
+    filter->Update();
+  } catch(std::runtime_error e) {
+    std::cout << e.what() << std::endl;
+    return EXIT_FAILURE;
+  }
+
+  return EXIT_SUCCESS;
+} // This is the end, my friend
+//--------------------------------------------------------------------
diff --git a/tools/clitkDice.ggo b/tools/clitkDice.ggo
new file mode 100644 (file)
index 0000000..3fcaeaf
--- /dev/null
@@ -0,0 +1,17 @@
+#File clitkDice.ggo
+package "clitkDice"
+version "1.0"
+purpose "Compute Dice between labeled images. Background must be 0."
+
+section "General options"
+option "config"                -       "Config file"                     string        no
+option "verbose"       v       "Verbose"                         flag          off
+option "imagetypes"     -       "Display allowed image types"     flag          off
+option "long"           l       "Long display (not only dice)"    flag          off
+
+section "Input"
+option "input1"         i      "Input mask 1"          string          yes
+option "input2"                j       "Input mask 2"          string          yes
+
+option "label1"                -       "Label in input1"       int          no      default="1"
+option "label2"                -       "Label in input2"       int          no      default="1"
index 59bf49e60ae955abcdd504e1f588fab0e33b88bf..7efc4e965161c8171f80f1d4157431fcdb02abd2 100644 (file)
@@ -19,6 +19,8 @@
 // clitk
 #include "clitkElastixTransformToMatrix_ggo.h"
 #include "clitkAffineTransformGenericFilter.h"
+#include "clitkElastix.h"
+#include "clitkMatrix.h"
 
 //--------------------------------------------------------------------
 int main(int argc, char * argv[])
@@ -29,21 +31,15 @@ int main(int argc, char * argv[])
   CLITK_INIT;
 
   // Use static fct of AffineTransformGenericFilter
-  typedef clitk::AffineTransformGenericFilter<args_info_clitkElastixTransformToMatrix> FilterType;
   std::vector<std::string> l;
   l.push_back(args_info.input_arg);
-  itk::Matrix<double, 4, 4> m = 
-    FilterType::createMatrixFromElastixFile<3, int>(l, args_info.verbose_flag);
+  itk::Matrix<double, 4, 4> m = clitk::createMatrixFromElastixFile<3>(l, args_info.verbose_flag);
 
   // Print matrix
   std::ofstream os;
   clitk::openFileForWriting(os, args_info.output_arg);
-  for(unsigned int i=0; i<4; i++) {
-    for(unsigned int j=0; j<4; j++)
-      os << m[i][j] << " ";
-    os << std::endl;
-  }
-  os.close();  
+  os << clitk::Get4x4MatrixDoubleAsString(m, 16);
+  os.close();
 
   return EXIT_SUCCESS;
 }// end main
diff --git a/tools/clitkImageUncertainty.cxx b/tools/clitkImageUncertainty.cxx
new file mode 100644 (file)
index 0000000..63b1f12
--- /dev/null
@@ -0,0 +1,115 @@
+/*=========================================================================
+
+  Program:   clitk
+  Module:    $RCSfile: clitkImageUncertainty.cxx,v $
+  Language:  C++
+  Date:      $Date: 2011/03/03 15:03:30 $
+  Version:   $Revision: 1.3 $
+
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#ifndef CLITKIMAGEUNCERTAINTY_CXX
+#define CLITKIMAGEUNCERTAINTY_CXX
+
+/**
+ =================================================
+ * @file   clitkImageUncertainty.cxx
+ * @author David Sarrut <david.sarrut@creatis.insa-lyon.fr>
+ * @date   04 Jul 2006 14:03:57
+ *
+ * @brief
+ *
+ *
+ =================================================*/
+
+// clitk include
+#include "clitkImageUncertainty_ggo.h"
+#include "clitkImageCommon.h"
+#include "clitkCommon.h"
+#include "clitkPortability.h"
+
+// itk include
+#include "itkImageRegionConstIterator.h"
+#include "itkImageRegionIterator.h"
+
+//====================================================================
+int main(int argc, char * argv[]) {
+
+  // init command line
+  GGO(clitkImageUncertainty, args_info);
+
+  // Declare main types
+  typedef float                          PixelType;
+  const unsigned int                              Dimension=3;
+  typedef itk::Image< PixelType, Dimension >      ImageType;
+
+  // Read images
+  ImageType::Pointer input =
+       clitk::readImage<ImageType>(args_info.input_arg, args_info.verbose_flag);
+  ImageType::Pointer inputSquared =
+       clitk::readImage<ImageType>(args_info.inputSquared_arg, args_info.verbose_flag);
+
+  // Create Output
+  ImageType::Pointer output = ImageType::New();
+  output->SetRegions(input->GetLargestPossibleRegion());
+  output->CopyInformation(input);
+  output->Allocate();
+
+  // Loop
+  typedef itk::ImageRegionConstIterator<ImageType> ConstIteratorType;
+  ConstIteratorType pi(input, input->GetLargestPossibleRegion());
+  ConstIteratorType pii(inputSquared, inputSquared->GetLargestPossibleRegion());
+  pi.GoToBegin();
+  pii.GoToBegin();
+  typedef itk::ImageRegionIterator<ImageType> IteratorType;
+  IteratorType po(output, output->GetLargestPossibleRegion());
+  po.GoToBegin();
+
+  int NumberOfEvents = args_info.NumberOfEvents_arg;
+  while ( !pi.IsAtEnd() ) {
+       double squared = pii.Get();
+       double mean = pi.Get();
+       double uncert = sqrt((NumberOfEvents*squared - mean*mean) / ((NumberOfEvents-1)*(mean*mean)));
+       if (!IsNormal(uncert)) uncert = 1.;
+       po.Set(uncert);
+       ++pi;
+       ++pii;
+       ++po;
+  }
+//       *po = sqrt( (NumberOfEvents*squared - mean*mean) /
+// ((NumberOfEvents-1)*(mean*mean)) );
+//       ++po;
+
+
+
+  // Write output image
+  // DD(clitk::GetExtension(args_info.output_arg));
+  if (clitk::GetExtension(args_info.output_arg) != "txt") {
+       clitk::writeImage<ImageType>(output, args_info.output_arg, args_info.verbose_flag);
+  }
+  else {
+       std::ofstream os;
+       clitk::openFileForWriting(os, args_info.output_arg);
+       typedef itk::ImageRegionConstIterator<ImageType> IteratorType;
+       IteratorType pi(output, output->GetLargestPossibleRegion());
+       pi.GoToBegin();
+       os << "# Image size = " << output->GetLargestPossibleRegion().GetSize() << std::endl;
+       os << "# Image spacing = " << output->GetSpacing() << std::endl;
+       os << "# Number of events = " << NumberOfEvents << std::endl;
+       while (!pi.IsAtEnd()) {
+         os << pi.Get() << std::endl;
+         ++pi;
+       }
+  }
+}
+
+
+#endif /* end #define CLITKIMAGEUNCERTAINTY_CXX */
diff --git a/tools/clitkImageUncertainty.ggo b/tools/clitkImageUncertainty.ggo
new file mode 100644 (file)
index 0000000..af5dfad
--- /dev/null
@@ -0,0 +1,10 @@
+# file clitkImageRescaleIntensity.ggo
+package "clitk"
+version "Rescale intensity in the image"
+
+option "config"                        -       "Config file"                                   string  no
+option "input"                 i       "Input image filename"                  string  yes
+option "inputSquared"  s       "Input squared image filename"  string  yes
+option "output"                        o       "Output image filename"                 string  yes
+option "NumberOfEvents" n   "Number of events"                         int     yes
+option "verbose"               v   "Verbose"                                           flag    off
diff --git a/tools/clitkLabelImageOverlapMeasureGenericFilter.h b/tools/clitkLabelImageOverlapMeasureGenericFilter.h
new file mode 100644 (file)
index 0000000..05332ea
--- /dev/null
@@ -0,0 +1,76 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+#ifndef CLITKLABELIMAGEOVERLAPMEASUREGENERICFILTER_H
+#define CLITKLABELIMAGEOVERLAPMEASUREGENERICFILTER_H
+
+// clitk
+#include "clitkImageToImageGenericFilter.h"
+#include "clitkLabelImageOverlapMeasureFilter.h"
+#include "clitkBoundingBoxUtils.h"
+#include "clitkCropLikeImageFilter.h"
+
+//--------------------------------------------------------------------
+namespace clitk
+{
+
+  template<class ArgsInfoType>
+  class ITK_EXPORT LabelImageOverlapMeasureGenericFilter:
+    public ImageToImageGenericFilter<LabelImageOverlapMeasureGenericFilter<ArgsInfoType> >
+  {
+  public:
+    //--------------------------------------------------------------------
+    LabelImageOverlapMeasureGenericFilter();
+
+    //--------------------------------------------------------------------
+    typedef ImageToImageGenericFilter<LabelImageOverlapMeasureGenericFilter<ArgsInfoType> > Superclass;
+    typedef LabelImageOverlapMeasureGenericFilter Self;
+    typedef itk::SmartPointer<Self>       Pointer;
+    typedef itk::SmartPointer<const Self> ConstPointer;
+
+    //--------------------------------------------------------------------
+    itkNewMacro(Self);
+    itkTypeMacro(LabelImageOverlapMeasureGenericFilter, LightObject);
+
+    //--------------------------------------------------------------------
+    void SetArgsInfo(const ArgsInfoType & a);
+    template<class FilterType>
+      void SetOptionsFromArgsInfoToFilter(FilterType * f) ;
+
+    //--------------------------------------------------------------------
+    // Main function called each time the filter is updated
+    template<class ImageType>
+    void UpdateWithInputImageType();
+
+  protected:
+    template<unsigned int Dim> void InitializeImageType();
+      ArgsInfoType mArgsInfo;
+
+  private:
+    LabelImageOverlapMeasureGenericFilter(const Self&); //purposely not implemented
+    void operator=(const Self&); //purposely not implemented
+
+  };// end class
+  //--------------------------------------------------------------------
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkLabelImageOverlapMeasureGenericFilter.txx"
+#endif
+
+#endif // #define CLITKRELATIVEPOSITIONANALYZERGENERICFILTER_H
diff --git a/tools/clitkLabelImageOverlapMeasureGenericFilter.txx b/tools/clitkLabelImageOverlapMeasureGenericFilter.txx
new file mode 100644 (file)
index 0000000..1ac11ee
--- /dev/null
@@ -0,0 +1,102 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ===========================================================================**/
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+clitk::LabelImageOverlapMeasureGenericFilter<ArgsInfoType>::
+LabelImageOverlapMeasureGenericFilter():
+  ImageToImageGenericFilter<Self>("LabelImageOverlapMeasure")
+{
+  // Default values
+  cmdline_parser_clitkDice_init(&mArgsInfo);
+  //InitializeImageType<2>();
+  InitializeImageType<3>();
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<unsigned int Dim>
+void clitk::LabelImageOverlapMeasureGenericFilter<ArgsInfoType>::
+InitializeImageType()
+{
+  ADD_IMAGE_TYPE(Dim, uchar);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+void clitk::LabelImageOverlapMeasureGenericFilter<ArgsInfoType>::
+SetArgsInfo(const ArgsInfoType & a)
+{
+  mArgsInfo=a;
+  //this->SetIOVerbose(mArgsInfo.verbose_flag);
+  if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
+  if (mArgsInfo.input1_given) this->AddInputFilename(mArgsInfo.input1_arg);
+  if (mArgsInfo.input2_given) this->AddInputFilename(mArgsInfo.input2_arg);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+// Update with the number of dimensions and the pixeltype
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class FilterType>
+void clitk::LabelImageOverlapMeasureGenericFilter<ArgsInfoType>::
+SetOptionsFromArgsInfoToFilter(FilterType * f)
+{
+  f->SetLabel1(mArgsInfo.label1_arg);
+  f->SetLabel2(mArgsInfo.label2_arg);
+  f->SetVerboseFlag(mArgsInfo.verbose_flag);
+  f->SetLongFlag(mArgsInfo.long_flag);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+// Update with the number of dimensions and the pixeltype
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class ImageType>
+void clitk::LabelImageOverlapMeasureGenericFilter<ArgsInfoType>::
+UpdateWithInputImageType()
+{
+  // Reading input
+  typename ImageType::Pointer input1 = this->template GetInput<ImageType>(0);
+  typename ImageType::Pointer input2 = this->template GetInput<ImageType>(1);
+
+  // Create filter
+  typedef clitk::LabelImageOverlapMeasureFilter<ImageType> FilterType;
+  typename FilterType::Pointer filter = FilterType::New();
+
+  // Set global Options
+  filter->SetInput(0, input1);
+  filter->SetInput(1, input2);
+  SetOptionsFromArgsInfoToFilter<FilterType>(filter);
+
+  // Go !
+  filter->Update();
+
+  // Write/Save results
+  // typename ImageType::Pointer output = filter->GetOutput();
+  // this->template SetNextOutput<ImageType>(output);
+}
+//--------------------------------------------------------------------
diff --git a/tools/clitkMatrixInverse.cxx b/tools/clitkMatrixInverse.cxx
new file mode 100644 (file)
index 0000000..7171467
--- /dev/null
@@ -0,0 +1,54 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+// clitk
+#include "clitkMatrixInverse_ggo.h"
+#include "clitkTransformUtilities.h"
+#include "clitkIO.h"
+#include "clitkMatrix.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+  // Init command line
+  GGO(clitkMatrixInverse, args_info);
+  CLITK_INIT;
+
+  // Read matrix
+  itk::Matrix<double, 4, 4> matrix;
+  try {
+    matrix = clitk::ReadMatrix3D(args_info.input_arg);
+  }
+  catch (itk::ExceptionObject & err) {
+    std::cerr << "Error reading " << args_info.input_arg << std::endl;
+    std::cerr << err.GetDescription() << std::endl;
+    exit(-1);
+  }
+
+  matrix = matrix.GetInverse();
+
+  // Print matrix
+  std::ofstream os;
+  clitk::openFileForWriting(os, args_info.output_arg);
+  os << clitk::Get4x4MatrixDoubleAsString(matrix, 16);
+  os.close();
+
+  return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
diff --git a/tools/clitkMatrixInverse.ggo b/tools/clitkMatrixInverse.ggo
new file mode 100644 (file)
index 0000000..391ae2f
--- /dev/null
@@ -0,0 +1,8 @@
+#File clitkMatrixToElastixTransform.ggo
+package "clitkMatrixInverse"
+version "1.0"
+purpose ""
+
+option "config"  - "Config file"            string optional
+option "input"   i "Input matrix filename"  string required
+option "output"  o "Output matrix filename" string required
diff --git a/tools/clitkMatrixToElastixTransform.cxx b/tools/clitkMatrixToElastixTransform.cxx
new file mode 100644 (file)
index 0000000..a8b7520
--- /dev/null
@@ -0,0 +1,118 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+// clitk
+#include "clitkMatrixToElastixTransform_ggo.h"
+#include "clitkTransformUtilities.h"
+#include "clitkIO.h"
+
+// itk
+#include <itkEuler3DTransform.h>
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+  // Init command line
+  GGO(clitkMatrixToElastixTransform, args_info);
+  CLITK_INIT;
+
+  // Read matrix
+  itk::Matrix<double, 4, 4> matrix;
+  try {
+    matrix = clitk::ReadMatrix3D(args_info.input_arg);
+  }
+  catch (itk::ExceptionObject & err) {
+    std::cerr << "Error reading " << args_info.input_arg << std::endl;
+    std::cerr << err.GetDescription() << std::endl;
+    exit(-1);
+  }
+
+  // Compute parameters from transfer using itk Euler transform
+  itk::Euler3DTransform<double>::CenterType center;
+  center.Fill(0.);
+  if(args_info.center_given==3) {
+    center[0] = args_info.center_arg[0];
+    center[1] = args_info.center_arg[1];
+    center[2] = args_info.center_arg[2];
+  }
+  itk::Euler3DTransform<double>::MatrixType rotMat;
+  itk::Euler3DTransform<double>::OutputVectorType transVec;
+  for(int i=0; i<3; i++) {
+    transVec[i] = matrix[i][3];
+    for(int j=0; j<3; j++)
+      rotMat[i][j] = matrix[i][j];
+  }
+  itk::Euler3DTransform<double>::Pointer euler;
+  euler = itk::Euler3DTransform<double>::New();
+  euler->SetCenter(center);
+  euler->SetOffset(transVec);
+  euler->SetComputeZYX(false);
+  try {
+    euler->SetMatrix(rotMat);
+  }
+  catch (itk::ExceptionObject & err) {
+    std::cerr << "Error reading " << args_info.input_arg << std::endl;
+    std::cerr << err.GetDescription() << std::endl;
+    exit(-1);
+  }
+
+  // Write result
+  std::ofstream out;
+  clitk::openFileForWriting(out, args_info.output_arg);
+  out << "(Transform \"EulerTransform\")" << std::endl;
+  out << "(NumberOfParameters 6)" << std::endl;
+  out << "(TransformParameters ";
+  for(unsigned int i=0; i<6; i++)
+    out << euler->GetParameters()[i] << ' ';
+  out << ')' << std::endl;
+  out << "(InitialTransformParametersFileName \"NoInitialTransform\")" << std::endl;
+  out << "(HowToCombineTransforms \"Compose\")" << std::endl;
+
+  out << "// EulerTransform specific" << std::endl;
+  out << "(CenterOfRotationPoint "<< center[0] << ' ' << center[1] << ' ' << center[2] << ')' << std::endl;
+  out << "(ComputeZYX \"false\")" << std::endl;
+
+  // The rest is commented, up to the user to define it manually
+  out << "// Image specific" << std::endl;
+  out << "// (FixedImageDimension 3)" << std::endl;
+  out << "// (MovingImageDimension 3)" << std::endl;
+  out << "// (FixedInternalImagePixelType \"float\")" << std::endl;
+  out << "// (MovingInternalImagePixelType \"float\")" << std::endl;
+  out << "// (Size 1 1 1)" << std::endl;
+  out << "// (Index 0 0 0)" << std::endl;
+  out << "// (Spacing 1 1 1)" << std::endl;
+  out << "// (Origin -0.5 -0.5 -0.5)" << std::endl;
+  out << "// (Direction 1 0 0 0 1 0 0 0 1)" << std::endl;
+  out << "// (UseDirectionCosines \"true\")" << std::endl << std::endl;
+
+  out << "// ResampleInterpolator specific" << std::endl;
+  out << "// (ResampleInterpolator \"FinalBSplineInterpolator\")" << std::endl;
+  out << "// (FinalBSplineInterpolationOrder 3)" << std::endl << std::endl;
+
+  out << "// Resampler specific" << std::endl;
+  out << "// (Resampler \"DefaultResampler\")" << std::endl;
+  out << "// (DefaultPixelValue 0.000000)" << std::endl;
+  out << "// (ResultImageFormat \"mhd\")" << std::endl;
+  out << "// (ResultImagePixelType \"short\")" << std::endl;
+  out << "// (CompressResultImage \"false\")" << std::endl;
+  out.close();
+
+  return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
diff --git a/tools/clitkMatrixToElastixTransform.ggo b/tools/clitkMatrixToElastixTransform.ggo
new file mode 100644 (file)
index 0000000..38f73fa
--- /dev/null
@@ -0,0 +1,10 @@
+#File clitkMatrixToElastixTransform.ggo
+package "clitkMatrixToElastixTransform"
+version "1.0"
+purpose ""
+
+option "config"  - "Config file"             string optional
+option "verbose" v "Verbose"                 flag   off
+option "input"   i "Input matrix filename"   string required
+option "output"  o "Output elastix filename" string required
+option "center"  - "Rotation center"         float     no multiple(3)
diff --git a/tools/clitkMergeAsciiDoseActor.cxx b/tools/clitkMergeAsciiDoseActor.cxx
new file mode 100644 (file)
index 0000000..4b1f861
--- /dev/null
@@ -0,0 +1,64 @@
+/*=========================================================================
+  Program:         vv http://www.creatis.insa-lyon.fr/rio/vv
+  Main authors :   XX XX XX
+
+  Authors belongs to: 
+  - University of LYON           http://www.universite-lyon.fr/
+  - Léon Bérard cancer center    http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory      http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+  - BSD       http://www.opensource.org/licenses/bsd-license.php
+  - CeCILL-B  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+
+  =========================================================================*/
+
+#include <fstream>
+#include "clitkCommon.h"
+#include "clitkMergeAsciiDoseActor_ggo.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+  // Init command line
+  GGO(clitkMergeAsciiDoseActor, args_info);
+
+  // Read input 1
+  std::vector<double> input1;
+  clitk::readDoubleFromFile(args_info.input1_arg, input1);
+  DD(input1.size());
+
+  // Read input 2
+  std::vector<double> input2;
+  clitk::readDoubleFromFile(args_info.input2_arg, input2);
+  DD(input2.size());
+
+  // Check 
+  if (input1.size() != input2.size()) {
+      std::cerr << "Error. Please provide input file with the same number of values. Read " 
+               << input1.size()  << " in " << args_info.input1_arg 
+               << " and " << input2.size() << " in " << args_info.input2_arg << std::endl;
+      exit(0);
+  }
+  
+  // Add
+  for(unsigned int i=0; i<input1.size(); i++) {
+    input1[i] += input2[i];
+  }
+
+  // Write output
+  std::ofstream os;
+  clitk::openFileForWriting(os, args_info.output_arg);
+  os << "## Merge " << input1.size() << " values" << std::endl;
+  for(unsigned int i=0; i<input1.size(); i++) {
+    os << input1[i] << std::endl;
+  }  
+  os.close();
+
+  // This is the end my friend 
+  return 0;
+}
diff --git a/tools/clitkMergeAsciiDoseActor.ggo b/tools/clitkMergeAsciiDoseActor.ggo
new file mode 100644 (file)
index 0000000..69f3695
--- /dev/null
@@ -0,0 +1,10 @@
+# file clitkMergeAsciiDoseActor.ggo
+package "clitk"
+version "Add values from two ASCII files (must contains list of numbers)"
+
+option "config"                 - "Config file"                 string         no
+option "input1"                 i "Input ASCII file"            string         yes
+option "input2"                 j "Input ASCII file"            string         yes
+option "output"                 o "Output ASCII file"           string         yes
+
+
diff --git a/tools/clitkMergeRootFiles.cxx b/tools/clitkMergeRootFiles.cxx
new file mode 100644 (file)
index 0000000..4bd0634
--- /dev/null
@@ -0,0 +1,122 @@
+/**
+   =================================================
+   * @file   clitkMergeRootFiles.cxx
+   * @author David Sarrut <david.sarrut@creatis.insa-lyon.fr>
+   * @date   01 Apr 2009
+   * 
+   * @brief  
+   * 
+   =================================================*/
+
+#include "clitkMergeRootFiles_ggo.h"
+#include "clitkCommon.h"
+#include "GateMergeManager.hh"
+#include <string> 
+#include <TROOT.h>
+#include <TPluginManager.h>
+#include <TFile.h>
+#include <TKey.h>
+#include <TFileMerger.h>
+#include <TTree.h>
+#include <TChain.h>
+#include <TH1.h>
+#include <TH2.h>
+#include <iostream>
+
+using std::endl;
+using std::cout;
+
+struct PetInputFile
+{
+       string filename;
+       double mean_time;
+};
+
+bool sort_pet_input_file(const PetInputFile& a, const PetInputFile& b)
+{
+       return a.mean_time<b.mean_time;
+};
+
+typedef std::vector<PetInputFile> PetInputFiles;
+
+//-----------------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo", "*",
+      "TStreamerInfo", "RIO", "TStreamerInfo()");
+
+  // init command line
+  GGO(clitkMergeRootFiles, args_info);
+
+  // Check parameters
+  if (args_info.input_given < 2) {
+    FATAL("Error, please provide at least two inputs files");
+  }
+
+  { // Detect Pet output
+         bool all_pet_output = true;
+         PetInputFiles pet_input_files;
+         for (uint i=0; i<args_info.input_given; i++) 
+         {
+                 const char* filename = args_info.input_arg[i];
+                 PetInputFile input_file;
+                 input_file.filename = filename;
+                 TFile* handle = TFile::Open(filename,"READ");
+                 assert(handle);
+                 TTree* hits = dynamic_cast<TTree*>(handle->Get("Hits"));
+                 TTree* singles = dynamic_cast<TTree*>(handle->Get("Singles"));
+                 const bool is_pet_output = (hits!=NULL) && (singles!=NULL);
+                 cout << "testing " << filename << " is_pet_output " << is_pet_output;
+
+                 if (is_pet_output)
+                 {
+                         double time;
+                         double time_accum = 0;
+                         singles->SetBranchAddress("time",&time);
+                         size_t total = singles->GetEntries();
+                         for (size_t kk=0; kk<total; kk++)
+                         {
+                                 singles->GetEntry(kk);
+                                 time_accum += time;
+                         }
+                                 
+                         input_file.mean_time = time_accum/total;
+                         pet_input_files.push_back(input_file);
+                         cout << " mean_time " << input_file.mean_time;
+                 }
+
+                 cout << endl;
+
+                 handle->Close();
+                 delete handle;
+                 all_pet_output &= is_pet_output;
+         }
+         cout << "all_pet_output " << all_pet_output << endl;
+
+         if (all_pet_output)
+         {
+                 GateMergeManager manager(args_info.fastmerge_given,args_info.verbose_arg,true,0,"");
+
+                 cout << "sorting input file using singles time" << endl;
+                 std::sort(pet_input_files.begin(),pet_input_files.end(),sort_pet_input_file);
+
+                 Strings input_filenames;
+                 for (PetInputFiles::const_iterator iter=pet_input_files.begin(); iter!=pet_input_files.end(); iter++)
+                         input_filenames.push_back(iter->filename);
+
+                 manager.StartMergingFromFilenames(input_filenames,args_info.output_arg);
+                 return 0;
+         }
+  }
+
+
+  // Merge
+  TFileMerger * merger = new TFileMerger;
+  for (uint i=0; i<args_info.input_given; i++) merger->AddFile(args_info.input_arg[i]);
+  merger->OutputFile(args_info.output_arg);
+  merger->Merge();
+
+  // this is the end my friend  
+  return 0;
+}
+//-----------------------------------------------------------------------------
diff --git a/tools/clitkMergeRootFiles.ggo b/tools/clitkMergeRootFiles.ggo
new file mode 100644 (file)
index 0000000..7baa396
--- /dev/null
@@ -0,0 +1,13 @@
+# --------------------------------------------
+# file clitkMergeRootFiles.ggo
+package "clitkMergeRootFiles"
+version "1.0"
+purpose "Merge several ROOT files"
+# --------------------------------------------
+
+option "config"                -  "Config file"               string no
+option "input"                 i  "Input ROOT filenames"      string multiple yes
+option "output"                o  "Output ROOT filename"      string yes
+option "fastmerge"             f  "Fast merge"                optional
+option "verbose"               v  "Verbose level"             int optional
+
index 42107987512a3c78686455c9e0f266ebb253b4e3..15e1d910c4163103205447bf5d35aebb8bb25d4b 100644 (file)
@@ -48,6 +48,7 @@ It is distributed under dual licence
 #include "vvSaveState.h"
 #include "vvReadState.h"
 #include "clitkConfiguration.h"
+#include "clitkMatrix.h"
 
 // ITK include
 #include <itkImage.h>
@@ -1145,7 +1146,7 @@ void vvMainWindow::ImageInfoChanged()
     infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
 
     transformation = imageSelected->GetTransform()[tSlice]->GetMatrix();
-    infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation));
+    infoPanel->setTransformation(clitk::Get4x4MatrixDoubleAsString(transformation).c_str());
 
     landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
                                         mSlicerManagers[index]->GetTSlice());
@@ -1343,38 +1344,6 @@ QString vvMainWindow::GetSizeInBytes(unsigned long size)
 }
 //------------------------------------------------------------------------------
 
-//------------------------------------------------------------------------------
-QString vvMainWindow::Get4x4MatrixDoubleAsString(vtkSmartPointer<vtkMatrix4x4> matrix, const int precision)
-{
-  std::ostringstream strmatrix;
-
-  // Figure out the number of digits of the integer part of the largest absolute value
-  // for each column
-  unsigned width[4];
-  for (unsigned int j = 0; j < 4; j++){
-    double absmax = 0.;
-    for (unsigned int i = 0; i < 4; i++)
-      absmax = std::max(absmax, vnl_math_abs(matrix->GetElement(i, j)));
-    unsigned ndigits = (unsigned)std::max(0.,std::log10(absmax))+1;
-    width[j] = precision+ndigits+3;
-  }
-
-  // Output with correct width, aligned to the right
-  for (unsigned int i = 0; i < 4; i++) {
-    for (unsigned int j = 0; j < 4; j++) {
-      strmatrix.setf(ios::fixed,ios::floatfield);
-      strmatrix.precision(precision);
-      strmatrix.fill(' ');
-      strmatrix.width(width[j]);
-      strmatrix << std::right << matrix->GetElement(i, j);
-    }
-    strmatrix << std::endl;
-  }
-  QString result = strmatrix.str().c_str();
-  return result;
-}
-//------------------------------------------------------------------------------
-
 //------------------------------------------------------------------------------
 QString vvMainWindow::GetVectorDoubleAsString(std::vector<double> vectorDouble)
 {
index e5e315509b1924c2392358cc36c6fe80c4e14fa4..b093554d0a0b92018d352f1eb1236db1012b8be6 100644 (file)
@@ -69,7 +69,6 @@ class vvMainWindow: public vvMainWindowBase,
   void SaveCurrentStateAs(const std::string& stateFile);
   void ReadSavedStateFile(const std::string& stateFile);
        void LinkAllImages();
-  QString Get4x4MatrixDoubleAsString(vtkSmartPointer<vtkMatrix4x4> matrix, const int precision=3);
 
   virtual void UpdateCurrentSlicer();
   virtual QTabWidget * GetTab();
index 508551da86a7dec2ed064921e170439f2d6faeff..29481651e21aad16311963d9557ea74155e107a1 100644 (file)
@@ -30,6 +30,7 @@
 
 // clitk
 #include "clitkTransformUtilities.h"
+#include "clitkMatrix.h"
 
 // qt
 #include <QMessageBox>
@@ -120,7 +121,7 @@ void vvToolRigidReg::InputIsSelected(vvSlicerManager *input)
     for(int i=0; i<4; i++)
       // TODO SR and BP: check on the list of transforms and not the first only
       mInitialMatrix->SetElement(i,j, mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix()->GetElement(i,j));
-  QString origTransformString = dynamic_cast<vvMainWindow*>(mMainWindow)->Get4x4MatrixDoubleAsString(mInitialMatrix);
+  QString origTransformString(clitk::Get4x4MatrixDoubleAsString(mInitialMatrix).c_str());
   transformationLabel->setText(origTransformString);
   SetTransform(mInitialMatrix);
 
@@ -298,7 +299,7 @@ void vvToolRigidReg::SaveFile()
   if (file.open(QFile::WriteOnly | QFile::Truncate)) {
     // TODO SR and BP: check on the list of transforms and not the first only
     vtkMatrix4x4* matrix = mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix();
-    QString matrixStr = dynamic_cast<vvMainWindow*>(mMainWindow)->Get4x4MatrixDoubleAsString(matrix,16);
+    QString matrixStr = clitk::Get4x4MatrixDoubleAsString(matrix,16).c_str();
     QTextStream out(&file);
     out << matrixStr;
   }