diff options
101 files changed, 2196 insertions, 1304 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ec0eafb --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +.*.swp +.*.swo +*~ +*.orig +*.rej +.nfs* + +/python/build/* +/python/finalbuild/* +/python/dist/* +/python/astra/*.pyc +/python/astra/*.cpp +/python/astra/*.c +/python/astra/config.pxi + +/build/linux/.libs/* +/build/linux/Makefile +/build/linux/aclocal.m4 +/build/linux/autom4te.cache/* +/build/linux/config.guess +/build/linux/config.log +/build/linux/config.status +/build/linux/config.sub +/build/linux/configure +/build/linux/cuda/* +/build/linux/install-sh +/build/linux/libastra.la +/build/linux/libtool +/build/linux/ltmain.sh +/build/linux/src/* +/build/linux/matlab/* @@ -9,6 +9,12 @@ Contact: astra@uantwerpen.be  Website: http://sf.net/projects/astra-toolbox  ----------------------------------------------------------------------- +1.6 (2015-05-29) +  * integrate and improve python interface +  * integrate opSpot-based opTomo operator +  * build fixes for newer platforms +  * various consistency and bug fixes +  1.5 (2015-01-30)    * add support for fan beam FBP    * remove limits on number of angles in GPU code @@ -23,12 +23,14 @@ Add the mex and tools subdirectories to your matlab path.  ### Linux, from source -Requirements: g++, boost, CUDA (driver+toolkit), matlab +Requirements: g++, boost, CUDA (driver+toolkit), Matlab and/or Python (2.7 or 3.x)  ```  cd build/linux +./autogen.sh   # when building a git version  ./configure --with-cuda=/usr/local/cuda \              --with-matlab=/usr/local/MATLAB/R2012a \ +            --with-python              --prefix=/usr/local/astra  make  make install @@ -36,6 +38,7 @@ make install  Add /usr/local/astra/lib to your LD_LIBRARY_PATH.  Add /usr/local/astra/matlab and its subdirectories (tools, mex)    to your matlab path. +Add /usr/local/astra/python to your PYTHONPATH.  NB: Each matlab version only supports a specific range of g++ versions. @@ -64,9 +67,14 @@ Install by copying AstraCuda32.dll or AstraCuda64.dll from bin/ and  ## References -If you use parallel beam GPU code for your research, we would appreciate it if you would refer to the following paper: +If you use the ASTRA Toolbox for your research, we would appreciate it if you would refer to the following paper: + +W. van Aarle, W. J. Palenstijn, J. De Beenhouwer, T. Altantzis, S. Bals,  K J. Batenburg, and J. Sijbers, "The ASTRA Toolbox: A platform for advanced algorithm development in electron tomography", Ultramicroscopy (2015), http://dx.doi.org/10.1016/j.ultramic.2015.05.002 + +Additionally, if you use parallel beam GPU code, we would appreciate it if you would refer to the following paper: + +W. J. Palenstijn, K J. Batenburg, and J. Sijbers, "Performance improvements for iterative electron tomography reconstruction using graphics processing units (GPUs)", Journal of Structural Biology, vol. 176, issue 2, pp. 250-253, 2011, http://dx.doi.org/10.1016/j.jsb.2011.07.017 -W. J. Palenstijn, K J. Batenburg, and J. Sijbers, "Performance improvements for iterative electron tomography reconstruction using graphics processing units (GPUs)", Journal of Structural Biology, vol. 176, issue 2, pp. 250-253, 2011.  ## License @@ -79,4 +87,4 @@ website: http://sf.net/projects/astra-toolbox  Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp             2014-2015, CWI, Amsterdam -           http://visielab.uantwerpen.be/ and http://www.cwi.nl/
\ No newline at end of file +           http://visielab.uantwerpen.be/ and http://www.cwi.nl/ @@ -49,17 +49,20 @@ Add the mex and tools subdirectories to your matlab path.  Linux, from source:  -------------------- -Requirements: g++, boost, CUDA (driver+toolkit), matlab +Requirements: g++, boost, CUDA (driver+toolkit), Matlab and/or Python (2.7 or 3.x)  cd build/linux +./autogen.sh   # when building a git version  ./configure --with-cuda=/usr/local/cuda \              --with-matlab=/usr/local/MATLAB/R2012a \ +            --with-python \              --prefix=/usr/local/astra  make  make install  Add /usr/local/astra/lib to your LD_LIBRARY_PATH.  Add /usr/local/astra/matlab and its subdirectories (tools, mex)    to your matlab path. +Add /usr/local/astra/python to your PYTHONPATH.  NB: Each matlab version only supports a specific range of g++ versions. @@ -90,11 +93,14 @@ Install by copying AstraCuda32.dll or AstraCuda64.dll from bin/ and  References:  ------------ -If you use parallel beam GPU code for your research, we would appreciate it if -you would refer to the following paper: +If you use the ASTRA Toolbox for your research, we would appreciate it if you would refer to the following paper: + +W. van Aarle, W. J. Palenstijn, J. De Beenhouwer, T. Altantzis, S. Bals,  K J. Batenburg, and J. Sijbers, "The ASTRA Toolbox: A platform for advanced algorithm development in electron tomography", Ultramicroscopy (2015), http://dx.doi.org/10.1016/j.ultramic.2015.05.002 + +Additionally, if you use parallel beam GPU code, we would appreciate it if you would refer to the following paper:  W. J. Palenstijn, K J. Batenburg, and J. Sijbers, "Performance improvements  for iterative electron tomography reconstruction using graphics processing  units (GPUs)", Journal of Structural Biology, vol. 176, issue 2, pp. 250-253, -2011 +2011, http://dx.doi.org/10.1016/j.jsb.2011.07.017 diff --git a/astra_vc09.vcproj b/astra_vc09.vcproj index a56e4bc..e5d7731 100644 --- a/astra_vc09.vcproj +++ b/astra_vc09.vcproj @@ -102,7 +102,8 @@  				Arch3="35"  				TargetMachinePlatform="0"  				Runtime="3" -				Defines="-DASTRA_CUDA -DDLL_EXPORTS" +				ExtraCppOptions="-Iinclude -Ilib/include" +				Defines="ASTRA_CUDA;DLL_EXPORTS"  			/>  		</Configuration>  		<Configuration @@ -186,7 +187,8 @@  				Arch3="35"  				TargetMachinePlatform="1"  				Runtime="3" -				Defines="-DASTRA_CUDA -DDLL_EXPORTS" +				ExtraCppOptions="-Iinclude -Ilib/include" +				Defines="ASTRA_CUDA;DLL_EXPORTS"  			/>  		</Configuration>  		<Configuration @@ -270,7 +272,8 @@  				Arch3="35"  				TargetMachinePlatform="0"  				Runtime="3" -				Defines="-DDLL_EXPORTS" +				ExtraCppOptions="-Iinclude -Ilib/include" +				Defines="DLL_EXPORTS"  			/>  		</Configuration>  		<Configuration @@ -353,7 +356,8 @@  				Arch3="35"  				TargetMachinePlatform="1"  				Runtime="3" -				Defines="-DDLL_EXPORTS" +				ExtraCppOptions="-Iinclude -Ilib/include" +				Defines="DLL_EXPORTS"  			/>  		</Configuration>  		<Configuration @@ -435,7 +439,8 @@  				Arch3="35"  				TargetMachinePlatform="0"  				Runtime="2" -				Defines="-DASTRA_CUDA -DDLL_EXPORTS" +				ExtraCppOptions="-Iinclude -Ilib/include" +				Defines="ASTRA_CUDA;DLL_EXPORTS"  			/>  		</Configuration>  		<Configuration @@ -516,7 +521,8 @@  				Arch3="35"  				TargetMachinePlatform="1"  				Runtime="2" -				Defines="-DASTRA_CUDA -DDLL_EXPORTS" +				ExtraCppOptions="-Iinclude -Ilib/include" +				Defines="ASTRA_CUDA;DLL_EXPORTS"  			/>  		</Configuration>  		<Configuration @@ -597,7 +603,8 @@  				Arch3="35"  				TargetMachinePlatform="0"  				Runtime="2" -				Defines="-DDLL_EXPORTS" +				ExtraCppOptions="-Iinclude -Ilib/include" +				Defines="DLL_EXPORTS"  			/>  		</Configuration>  		<Configuration @@ -677,7 +684,8 @@  				Arch3="35"  				TargetMachinePlatform="1"  				Runtime="2" -				Defines="-DDLL_EXPORTS" +				ExtraCppOptions="-Iinclude -Ilib/include" +				Defines="DLL_EXPORTS"  			/>  		</Configuration>  	</Configurations> diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in index 0dfa15a..2d862f2 100644 --- a/build/linux/Makefile.in +++ b/build/linux/Makefile.in @@ -28,7 +28,7 @@ CXXFLAGS=@SAVED_CXXFLAGS@  LDFLAGS=@SAVED_LDFLAGS@  LIBS=@SAVED_LIBS@ -CPPFLAGS+=-I../.. -I../../include -I../../lib/include/rapidxml +CPPFLAGS+=-I../.. -I../../include -I../../lib/include  CXXFLAGS+=-g -O3 -Wall -Wshadow  LIBS+=-lpthread  LDFLAGS+=-g diff --git a/build/linux/README.txt b/build/linux/README.txt index 9dd7a7a..7208d45 100644 --- a/build/linux/README.txt +++ b/build/linux/README.txt @@ -1,15 +1,17 @@ -Requirements: g++, boost, CUDA (driver+toolkit), -matlab +Requirements: g++, boost, CUDA (driver+toolkit), Matlab and/or Python (2.7 or 3.x)  cd build/linux +./autogen.sh   # when building a git version  ./configure --with-cuda=/usr/local/cuda \              --with-matlab=/usr/local/MATLAB/R2012a \ +            --with-python \              --prefix=/usr/local/astra  make  make install  Add /usr/local/astra/lib to your LD_LIBRARY_PATH.  Add /usr/local/astra/matlab and its subdirectories (tools, mex)    to your matlab path. +Add /usr/local/astra/python to your PYTHONPATH.  NB: Each matlab version only supports a specific range of g++ versions. diff --git a/build/linux/config.guess.dist b/build/linux/config.guess.dist index dc84c68..b79252d 100755 --- a/build/linux/config.guess.dist +++ b/build/linux/config.guess.dist @@ -1,14 +1,12 @@  #! /bin/sh  # Attempt to guess a canonical system name. -#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -#   Free Software Foundation, Inc. +#   Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2009-11-20' +timestamp='2013-06-10'  # This file is free software; you can redistribute it and/or modify it  # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or  # (at your option) any later version.  #  # This program is distributed in the hope that it will be useful, but @@ -17,26 +15,22 @@ timestamp='2009-11-20'  # General Public License for more details.  #  # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see <http://www.gnu.org/licenses/>.  #  # As a special exception to the GNU General Public License, if you  # distribute this file as part of a program that contains a  # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner.  Please send patches (context -# diff format) to <config-patches@gnu.org> and include a ChangeLog -# entry. +# the same distribution terms that you use for the rest of that +# program.  This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3").  # -# This script attempts to guess a canonical system name similar to -# config.sub.  If it succeeds, it prints the system name on stdout, and -# exits with 0.  Otherwise, it exits with 1. +# Originally written by Per Bothner.  #  # You can get the latest version of this script from:  # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. +  me=`echo "$0" | sed -e 's,.*/,,'` @@ -56,8 +50,7 @@ version="\  GNU config.guess ($timestamp)  Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc.  This is free software; see the source for copying conditions.  There is NO  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -139,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown  UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown  UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) +	# If the system lacks a compiler, then just pick glibc. +	# We could probably try harder. +	LIBC=gnu + +	eval $set_cc_for_build +	cat <<-EOF > $dummy.c +	#include <features.h> +	#if defined(__UCLIBC__) +	LIBC=uclibc +	#elif defined(__dietlibc__) +	LIBC=dietlibc +	#else +	LIBC=gnu +	#endif +	EOF +	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` +	;; +esac +  # Note: order is significant - the case branches are not exclusive.  case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in      *:NetBSD:*:*)  	# NetBSD (nbsd) targets should (where applicable) match one or -	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, +	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,  	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently  	# switched to ELF, *-*-netbsd* would select the old  	# object file format.  This provides both forward @@ -180,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in  		fi  		;;  	    *) -	        os=netbsd +		os=netbsd  		;;  	esac  	# The OS release @@ -201,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in  	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.  	echo "${machine}-${os}${release}"  	exit ;; +    *:Bitrig:*:*) +	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` +	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} +	exit ;;      *:OpenBSD:*:*)  	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`  	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} @@ -223,7 +241,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in  		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`  		;;  	*5.*) -	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` +		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`  		;;  	esac  	# According to Compaq, /usr/sbin/psrinfo has been available on @@ -269,7 +287,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in  	# A Xn.n version is an unreleased experimental baselevel.  	# 1.2 uses "1.2" for uname -r.  	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` -	exit ;; +	# Reset EXIT trap before exiting to avoid spurious non-zero exit code. +	exitcode=$? +	trap '' 0 +	exit $exitcode ;;      Alpha\ *:Windows_NT*:*)  	# How do we know it's Interix rather than the generic POSIX subsystem?  	# Should we change UNAME_MACHINE based on the output of uname instead @@ -295,12 +316,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in  	echo s390-ibm-zvmoe  	exit ;;      *:OS400:*:*) -        echo powerpc-ibm-os400 +	echo powerpc-ibm-os400  	exit ;;      arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)  	echo arm-acorn-riscix${UNAME_RELEASE}  	exit ;; -    arm:riscos:*:*|arm:RISCOS:*:*) +    arm*:riscos:*:*|arm*:RISCOS:*:*)  	echo arm-unknown-riscos  	exit ;;      SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -394,23 +415,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in      # MiNT.  But MiNT is downward compatible to TOS, so this should      # be no problem.      atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) -        echo m68k-atari-mint${UNAME_RELEASE} +	echo m68k-atari-mint${UNAME_RELEASE}  	exit ;;      atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)  	echo m68k-atari-mint${UNAME_RELEASE} -        exit ;; +	exit ;;      *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) -        echo m68k-atari-mint${UNAME_RELEASE} +	echo m68k-atari-mint${UNAME_RELEASE}  	exit ;;      milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) -        echo m68k-milan-mint${UNAME_RELEASE} -        exit ;; +	echo m68k-milan-mint${UNAME_RELEASE} +	exit ;;      hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) -        echo m68k-hades-mint${UNAME_RELEASE} -        exit ;; +	echo m68k-hades-mint${UNAME_RELEASE} +	exit ;;      *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) -        echo m68k-unknown-mint${UNAME_RELEASE} -        exit ;; +	echo m68k-unknown-mint${UNAME_RELEASE} +	exit ;;      m68k:machten:*:*)  	echo m68k-apple-machten${UNAME_RELEASE}  	exit ;; @@ -480,8 +501,8 @@ EOF  	echo m88k-motorola-sysv3  	exit ;;      AViiON:dgux:*:*) -        # DG/UX returns AViiON for all architectures -        UNAME_PROCESSOR=`/usr/bin/uname -p` +	# DG/UX returns AViiON for all architectures +	UNAME_PROCESSOR=`/usr/bin/uname -p`  	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]  	then  	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ @@ -494,7 +515,7 @@ EOF  	else  	    echo i586-dg-dgux${UNAME_RELEASE}  	fi - 	exit ;; +	exit ;;      M88*:DolphinOS:*:*)	# DolphinOS (SVR3)  	echo m88k-dolphin-sysv3  	exit ;; @@ -551,7 +572,7 @@ EOF  		echo rs6000-ibm-aix3.2  	fi  	exit ;; -    *:AIX:*:[456]) +    *:AIX:*:[4567])  	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`  	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then  		IBM_ARCH=rs6000 @@ -594,52 +615,52 @@ EOF  	    9000/[678][0-9][0-9])  		if [ -x /usr/bin/getconf ]; then  		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` -                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` -                    case "${sc_cpu_version}" in -                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 -                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 -                      532)                      # CPU_PA_RISC2_0 -                        case "${sc_kernel_bits}" in -                          32) HP_ARCH="hppa2.0n" ;; -                          64) HP_ARCH="hppa2.0w" ;; +		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` +		    case "${sc_cpu_version}" in +		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 +		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 +		      532)                      # CPU_PA_RISC2_0 +			case "${sc_kernel_bits}" in +			  32) HP_ARCH="hppa2.0n" ;; +			  64) HP_ARCH="hppa2.0w" ;;  			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20 -                        esac ;; -                    esac +			esac ;; +		    esac  		fi  		if [ "${HP_ARCH}" = "" ]; then  		    eval $set_cc_for_build -		    sed 's/^              //' << EOF >$dummy.c +		    sed 's/^		//' << EOF >$dummy.c -              #define _HPUX_SOURCE -              #include <stdlib.h> -              #include <unistd.h> +		#define _HPUX_SOURCE +		#include <stdlib.h> +		#include <unistd.h> -              int main () -              { -              #if defined(_SC_KERNEL_BITS) -                  long bits = sysconf(_SC_KERNEL_BITS); -              #endif -                  long cpu  = sysconf (_SC_CPU_VERSION); +		int main () +		{ +		#if defined(_SC_KERNEL_BITS) +		    long bits = sysconf(_SC_KERNEL_BITS); +		#endif +		    long cpu  = sysconf (_SC_CPU_VERSION); -                  switch (cpu) -              	{ -              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break; -              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break; -              	case CPU_PA_RISC2_0: -              #if defined(_SC_KERNEL_BITS) -              	    switch (bits) -              		{ -              		case 64: puts ("hppa2.0w"); break; -              		case 32: puts ("hppa2.0n"); break; -              		default: puts ("hppa2.0"); break; -              		} break; -              #else  /* !defined(_SC_KERNEL_BITS) */ -              	    puts ("hppa2.0"); break; -              #endif -              	default: puts ("hppa1.0"); break; -              	} -                  exit (0); -              } +		    switch (cpu) +			{ +			case CPU_PA_RISC1_0: puts ("hppa1.0"); break; +			case CPU_PA_RISC1_1: puts ("hppa1.1"); break; +			case CPU_PA_RISC2_0: +		#if defined(_SC_KERNEL_BITS) +			    switch (bits) +				{ +				case 64: puts ("hppa2.0w"); break; +				case 32: puts ("hppa2.0n"); break; +				default: puts ("hppa2.0"); break; +				} break; +		#else  /* !defined(_SC_KERNEL_BITS) */ +			    puts ("hppa2.0"); break; +		#endif +			default: puts ("hppa1.0"); break; +			} +		    exit (0); +		}  EOF  		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`  		    test -z "$HP_ARCH" && HP_ARCH=hppa @@ -730,22 +751,22 @@ EOF  	exit ;;      C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)  	echo c1-convex-bsd -        exit ;; +	exit ;;      C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)  	if getsysinfo -f scalar_acc  	then echo c32-convex-bsd  	else echo c2-convex-bsd  	fi -        exit ;; +	exit ;;      C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)  	echo c34-convex-bsd -        exit ;; +	exit ;;      C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)  	echo c38-convex-bsd -        exit ;; +	exit ;;      C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)  	echo c4-convex-bsd -        exit ;; +	exit ;;      CRAY*Y-MP:*:*:*)  	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'  	exit ;; @@ -769,14 +790,14 @@ EOF  	exit ;;      F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)  	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` -        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` -        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` -        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" -        exit ;; +	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` +	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` +	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" +	exit ;;      5000:UNIX_System_V:4.*:*) -        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` -        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` -        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" +	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` +	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` +	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"  	exit ;;      i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)  	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} @@ -788,30 +809,35 @@ EOF  	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}  	exit ;;      *:FreeBSD:*:*) -	case ${UNAME_MACHINE} in -	    pc98) -		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; +	UNAME_PROCESSOR=`/usr/bin/uname -p` +	case ${UNAME_PROCESSOR} in  	    amd64)  		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;  	    *) -		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; +		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;  	esac  	exit ;;      i*:CYGWIN*:*)  	echo ${UNAME_MACHINE}-pc-cygwin  	exit ;; +    *:MINGW64*:*) +	echo ${UNAME_MACHINE}-pc-mingw64 +	exit ;;      *:MINGW*:*)  	echo ${UNAME_MACHINE}-pc-mingw32  	exit ;; +    i*:MSYS*:*) +	echo ${UNAME_MACHINE}-pc-msys +	exit ;;      i*:windows32*:*) -    	# uname -m includes "-pc" on this system. -    	echo ${UNAME_MACHINE}-mingw32 +	# uname -m includes "-pc" on this system. +	echo ${UNAME_MACHINE}-mingw32  	exit ;;      i*:PW*:*)  	echo ${UNAME_MACHINE}-pc-pw32  	exit ;;      *:Interix*:*) -    	case ${UNAME_MACHINE} in +	case ${UNAME_MACHINE} in  	    x86)  		echo i586-pc-interix${UNAME_RELEASE}  		exit ;; @@ -848,15 +874,22 @@ EOF  	exit ;;      *:GNU:*:*)  	# the GNU system -	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` +	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`  	exit ;;      *:GNU/*:*:*)  	# other systems with GNU libc and userland -	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu +	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}  	exit ;;      i*86:Minix:*:*)  	echo ${UNAME_MACHINE}-pc-minix  	exit ;; +    aarch64:Linux:*:*) +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +	exit ;; +    aarch64_be:Linux:*:*) +	UNAME_MACHINE=aarch64_be +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +	exit ;;      alpha:Linux:*:*)  	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in  	  EV5)   UNAME_MACHINE=alphaev5 ;; @@ -866,52 +899,56 @@ EOF  	  EV6)   UNAME_MACHINE=alphaev6 ;;  	  EV67)  UNAME_MACHINE=alphaev67 ;;  	  EV68*) UNAME_MACHINE=alphaev68 ;; -        esac +	esac  	objdump --private-headers /bin/sh | grep -q ld.so.1 -	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi -	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} +	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +	exit ;; +    arc:Linux:*:* | arceb:Linux:*:*) +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      arm*:Linux:*:*)  	eval $set_cc_for_build  	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \  	    | grep -q __ARM_EABI__  	then -	    echo ${UNAME_MACHINE}-unknown-linux-gnu +	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	else -	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi +	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ +		| grep -q __ARM_PCS_VFP +	    then +		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi +	    else +		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf +	    fi  	fi  	exit ;;      avr32*:Linux:*:*) -	echo ${UNAME_MACHINE}-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      cris:Linux:*:*) -	echo cris-axis-linux-gnu +	echo ${UNAME_MACHINE}-axis-linux-${LIBC}  	exit ;;      crisv32:Linux:*:*) -	echo crisv32-axis-linux-gnu +	echo ${UNAME_MACHINE}-axis-linux-${LIBC}  	exit ;;      frv:Linux:*:*) -    	echo frv-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +	exit ;; +    hexagon:Linux:*:*) +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      i*86:Linux:*:*) -	LIBC=gnu -	eval $set_cc_for_build -	sed 's/^	//' << EOF >$dummy.c -	#ifdef __dietlibc__ -	LIBC=dietlibc -	#endif -EOF -	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` -	echo "${UNAME_MACHINE}-pc-linux-${LIBC}" +	echo ${UNAME_MACHINE}-pc-linux-${LIBC}  	exit ;;      ia64:Linux:*:*) -	echo ${UNAME_MACHINE}-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      m32r*:Linux:*:*) -	echo ${UNAME_MACHINE}-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      m68*:Linux:*:*) -	echo ${UNAME_MACHINE}-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      mips:Linux:*:* | mips64:Linux:*:*)  	eval $set_cc_for_build @@ -930,51 +967,63 @@ EOF  	#endif  EOF  	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` -	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } +	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }  	;; +    or1k:Linux:*:*) +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +	exit ;;      or32:Linux:*:*) -	echo or32-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      padre:Linux:*:*) -	echo sparc-unknown-linux-gnu +	echo sparc-unknown-linux-${LIBC}  	exit ;;      parisc64:Linux:*:* | hppa64:Linux:*:*) -	echo hppa64-unknown-linux-gnu +	echo hppa64-unknown-linux-${LIBC}  	exit ;;      parisc:Linux:*:* | hppa:Linux:*:*)  	# Look for CPU level  	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in -	  PA7*) echo hppa1.1-unknown-linux-gnu ;; -	  PA8*) echo hppa2.0-unknown-linux-gnu ;; -	  *)    echo hppa-unknown-linux-gnu ;; +	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; +	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; +	  *)    echo hppa-unknown-linux-${LIBC} ;;  	esac  	exit ;;      ppc64:Linux:*:*) -	echo powerpc64-unknown-linux-gnu +	echo powerpc64-unknown-linux-${LIBC}  	exit ;;      ppc:Linux:*:*) -	echo powerpc-unknown-linux-gnu +	echo powerpc-unknown-linux-${LIBC} +	exit ;; +    ppc64le:Linux:*:*) +	echo powerpc64le-unknown-linux-${LIBC} +	exit ;; +    ppcle:Linux:*:*) +	echo powerpcle-unknown-linux-${LIBC}  	exit ;;      s390:Linux:*:* | s390x:Linux:*:*) -	echo ${UNAME_MACHINE}-ibm-linux +	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}  	exit ;;      sh64*:Linux:*:*) -    	echo ${UNAME_MACHINE}-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      sh*:Linux:*:*) -	echo ${UNAME_MACHINE}-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      sparc:Linux:*:* | sparc64:Linux:*:*) -	echo ${UNAME_MACHINE}-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +	exit ;; +    tile*:Linux:*:*) +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      vax:Linux:*:*) -	echo ${UNAME_MACHINE}-dec-linux-gnu +	echo ${UNAME_MACHINE}-dec-linux-${LIBC}  	exit ;;      x86_64:Linux:*:*) -	echo x86_64-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      xtensa*:Linux:*:*) -    	echo ${UNAME_MACHINE}-unknown-linux-gnu +	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}  	exit ;;      i*86:DYNIX/ptx:4*:*)  	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -983,11 +1032,11 @@ EOF  	echo i386-sequent-sysv4  	exit ;;      i*86:UNIX_SV:4.2MP:2.*) -        # Unixware is an offshoot of SVR4, but it has its own version -        # number series starting with 2... -        # I am not positive that other SVR4 systems won't match this, +	# Unixware is an offshoot of SVR4, but it has its own version +	# number series starting with 2... +	# I am not positive that other SVR4 systems won't match this,  	# I just have to hope.  -- rms. -        # Use sysv4.2uw... so that sysv4* matches it. +	# Use sysv4.2uw... so that sysv4* matches it.  	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}  	exit ;;      i*86:OS/2:*:*) @@ -1019,7 +1068,7 @@ EOF  	fi  	exit ;;      i*86:*:5:[678]*) -    	# UnixWare 7.x, OpenUNIX and OpenServer 6. +	# UnixWare 7.x, OpenUNIX and OpenServer 6.  	case `/bin/uname -X | grep "^Machine"` in  	    *486*)	     UNAME_MACHINE=i486 ;;  	    *Pentium)	     UNAME_MACHINE=i586 ;; @@ -1047,13 +1096,13 @@ EOF  	exit ;;      pc:*:*:*)  	# Left here for compatibility: -        # uname -m prints for DJGPP always 'pc', but it prints nothing about -        # the processor, so we play safe by assuming i586. +	# uname -m prints for DJGPP always 'pc', but it prints nothing about +	# the processor, so we play safe by assuming i586.  	# Note: whatever this is, it MUST be the same as what config.sub  	# prints for the "djgpp" host, or else GDB configury will decide that  	# this is a cross-build.  	echo i586-pc-msdosdjgpp -        exit ;; +	exit ;;      Intel:Mach:3*:*)  	echo i386-pc-mach3  	exit ;; @@ -1088,8 +1137,8 @@ EOF  	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \  	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;      3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) -        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ -          && { echo i486-ncr-sysv4; exit; } ;; +	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \ +	  && { echo i486-ncr-sysv4; exit; } ;;      NCR*:*:4.2:* | MPRAS*:*:4.2:*)  	OS_REL='.3'  	test -r /etc/.relid \ @@ -1132,10 +1181,10 @@ EOF  		echo ns32k-sni-sysv  	fi  	exit ;; -    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort -                      # says <Richard.M.Bartel@ccMail.Census.GOV> -        echo i586-unisys-sysv4 -        exit ;; +    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort +			# says <Richard.M.Bartel@ccMail.Census.GOV> +	echo i586-unisys-sysv4 +	exit ;;      *:UNIX_System_V:4*:FTX*)  	# From Gerald Hewes <hewes@openmarket.com>.  	# How about differentiating between stratus architectures? -djm @@ -1161,11 +1210,11 @@ EOF  	exit ;;      R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)  	if [ -d /usr/nec ]; then -	        echo mips-nec-sysv${UNAME_RELEASE} +		echo mips-nec-sysv${UNAME_RELEASE}  	else -	        echo mips-unknown-sysv${UNAME_RELEASE} +		echo mips-unknown-sysv${UNAME_RELEASE}  	fi -        exit ;; +	exit ;;      BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.  	echo powerpc-be-beos  	exit ;; @@ -1178,6 +1227,9 @@ EOF      BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.  	echo i586-pc-haiku  	exit ;; +    x86_64:Haiku:*:*) +	echo x86_64-unknown-haiku +	exit ;;      SX-4:SUPER-UX:*:*)  	echo sx4-nec-superux${UNAME_RELEASE}  	exit ;; @@ -1204,19 +1256,21 @@ EOF  	exit ;;      *:Darwin:*:*)  	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown -	case $UNAME_PROCESSOR in -	    i386) -		eval $set_cc_for_build -		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then -		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ -		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ -		      grep IS_64BIT_ARCH >/dev/null -		  then -		      UNAME_PROCESSOR="x86_64" -		  fi -		fi ;; -	    unknown) UNAME_PROCESSOR=powerpc ;; -	esac +	eval $set_cc_for_build +	if test "$UNAME_PROCESSOR" = unknown ; then +	    UNAME_PROCESSOR=powerpc +	fi +	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then +	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ +		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ +		grep IS_64BIT_ARCH >/dev/null +	    then +		case $UNAME_PROCESSOR in +		    i386) UNAME_PROCESSOR=x86_64 ;; +		    powerpc) UNAME_PROCESSOR=powerpc64 ;; +		esac +	    fi +	fi  	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}  	exit ;;      *:procnto*:*:* | *:QNX:[0123456789]*:*) @@ -1230,7 +1284,10 @@ EOF      *:QNX:*:4*)  	echo i386-pc-qnx  	exit ;; -    NSE-?:NONSTOP_KERNEL:*:*) +    NEO-?:NONSTOP_KERNEL:*:*) +	echo neo-tandem-nsk${UNAME_RELEASE} +	exit ;; +    NSE-*:NONSTOP_KERNEL:*:*)  	echo nse-tandem-nsk${UNAME_RELEASE}  	exit ;;      NSR-?:NONSTOP_KERNEL:*:*) @@ -1275,13 +1332,13 @@ EOF  	echo pdp10-unknown-its  	exit ;;      SEI:*:*:SEIUX) -        echo mips-sei-seiux${UNAME_RELEASE} +	echo mips-sei-seiux${UNAME_RELEASE}  	exit ;;      *:DragonFly:*:*)  	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`  	exit ;;      *:*VMS:*:*) -    	UNAME_MACHINE=`(uname -p) 2>/dev/null` +	UNAME_MACHINE=`(uname -p) 2>/dev/null`  	case "${UNAME_MACHINE}" in  	    A*) echo alpha-dec-vms ; exit ;;  	    I*) echo ia64-dec-vms ; exit ;; @@ -1299,11 +1356,11 @@ EOF      i*86:AROS:*:*)  	echo ${UNAME_MACHINE}-pc-aros  	exit ;; +    x86_64:VMkernel:*:*) +	echo ${UNAME_MACHINE}-unknown-esx +	exit ;;  esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 -  eval $set_cc_for_build  cat >$dummy.c <<EOF  #ifdef _SEQUENT_ @@ -1321,11 +1378,11 @@ main ()  #include <sys/param.h>    printf ("m68k-sony-newsos%s\n",  #ifdef NEWSOS4 -          "4" +	"4"  #else -	  "" +	""  #endif -         ); exit (0); +	); exit (0);  #endif  #endif diff --git a/build/linux/config.sub.dist b/build/linux/config.sub.dist index 2a55a50..d2a9613 100755 --- a/build/linux/config.sub.dist +++ b/build/linux/config.sub.dist @@ -1,38 +1,31 @@  #! /bin/sh  # Configuration validation subroutine script. -#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -#   Free Software Foundation, Inc. +#   Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2009-11-20' +timestamp='2013-08-10' -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine.  It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or  # (at your option) any later version.  # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +# General Public License for more details.  #  # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see <http://www.gnu.org/licenses/>.  #  # As a special exception to the GNU General Public License, if you  # distribute this file as part of a program that contains a  # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program.  This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to <config-patches@gnu.org>.  Submit a context -# diff and a properly formatted GNU ChangeLog entry. +# Please send patches with a ChangeLog entry to config-patches@gnu.org.  #  # Configuration subroutine to validate and canonicalize a configuration type.  # Supply the specified configuration type as an argument. @@ -75,8 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."  version="\  GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc.  This is free software; see the source for copying conditions.  There is NO  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -123,13 +115,18 @@ esac  # Here we must recognize all the valid KERNEL-OS combinations.  maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`  case $maybe_os in -  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ -  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ +  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ +  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ +  knetbsd*-gnu* | netbsd*-gnu* | \    kopensolaris*-gnu* | \    storm-chaos* | os2-emx* | rtmk-nova*)      os=-$maybe_os      basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`      ;; +  android-linux) +    os=-linux-android +    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown +    ;;    *)      basic_machine=`echo $1 | sed 's/-[^-]*$//'`      if [ $basic_machine != $1 ] @@ -152,12 +149,12 @@ case $os in  	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\  	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \  	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -	-apple | -axis | -knuth | -cray | -microblaze) +	-apple | -axis | -knuth | -cray | -microblaze*)  		os=  		basic_machine=$1  		;; -        -bluegene*) -	        os=-cnk +	-bluegene*) +		os=-cnk  		;;  	-sim | -cisco | -oki | -wec | -winbond)  		os= @@ -173,10 +170,10 @@ case $os in  		os=-chorusos  		basic_machine=$1  		;; - 	-chorusrdb) - 		os=-chorusrdb +	-chorusrdb) +		os=-chorusrdb  		basic_machine=$1 - 		;; +		;;  	-hiux*)  		os=-hiuxwe2  		;; @@ -221,6 +218,12 @@ case $os in  	-isc*)  		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`  		;; +	-lynx*178) +		os=-lynxos178 +		;; +	-lynx*5) +		os=-lynxos5 +		;;  	-lynx*)  		os=-lynxos  		;; @@ -245,20 +248,27 @@ case $basic_machine in  	# Some are omitted here because they have special meanings below.  	1750a | 580 \  	| a29k \ +	| aarch64 | aarch64_be \  	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \  	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \  	| am33_2.0 \ -	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ +	| arc | arceb \ +	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ +	| avr | avr32 \ +	| be32 | be64 \  	| bfin \ -	| c4x | clipper \ +	| c4x | c8051 | clipper \  	| d10v | d30v | dlx | dsp16xx \ +	| epiphany \  	| fido | fr30 | frv \  	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ +	| hexagon \  	| i370 | i860 | i960 | ia64 \  	| ip2k | iq2000 \ +	| le32 | le64 \  	| lm32 \  	| m32c | m32r | m32rle | m68000 | m68k | m88k \ -	| maxq | mb | microblaze | mcore | mep | metag \ +	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \  	| mips | mipsbe | mipseb | mipsel | mipsle \  	| mips16 \  	| mips64 | mips64el \ @@ -276,34 +286,45 @@ case $basic_machine in  	| mipsisa64r2 | mipsisa64r2el \  	| mipsisa64sb1 | mipsisa64sb1el \  	| mipsisa64sr71k | mipsisa64sr71kel \ +	| mipsr5900 | mipsr5900el \  	| mipstx39 | mipstx39el \  	| mn10200 | mn10300 \  	| moxie \  	| mt \  	| msp430 \ -	| nios | nios2 \ +	| nds32 | nds32le | nds32be \ +	| nios | nios2 | nios2eb | nios2el \  	| ns16k | ns32k \ -	| or32 \ +	| open8 \ +	| or1k | or32 \  	| pdp10 | pdp11 | pj | pjl \ -	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ +	| powerpc | powerpc64 | powerpc64le | powerpcle \  	| pyramid \ -	| rx \ +	| rl78 | rx \  	| score \  	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \  	| sh64 | sh64le \  	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \  	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \ -	| spu | strongarm \ -	| tahoe | thumb | tic4x | tic80 | tron \ +	| spu \ +	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \  	| ubicom32 \ -	| v850 | v850e \ +	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \  	| we32k \ -	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ +	| x86 | xc16x | xstormy16 | xtensa \  	| z8k | z80)  		basic_machine=$basic_machine-unknown  		;; -	m6811 | m68hc11 | m6812 | m68hc12 | picochip) -		# Motorola 68HC11/12. +	c54x) +		basic_machine=tic54x-unknown +		;; +	c55x) +		basic_machine=tic55x-unknown +		;; +	c6x) +		basic_machine=tic6x-unknown +		;; +	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)  		basic_machine=$basic_machine-unknown  		os=-none  		;; @@ -313,6 +334,21 @@ case $basic_machine in  		basic_machine=mt-unknown  		;; +	strongarm | thumb | xscale) +		basic_machine=arm-unknown +		;; +	xgate) +		basic_machine=$basic_machine-unknown +		os=-none +		;; +	xscaleeb) +		basic_machine=armeb-unknown +		;; + +	xscaleel) +		basic_machine=armel-unknown +		;; +  	# We use `pc' rather than `unknown'  	# because (1) that's what they normally are, and  	# (2) the word "unknown" tends to confuse beginning users. @@ -327,25 +363,30 @@ case $basic_machine in  	# Recognize the basic CPU types with company name.  	580-* \  	| a29k-* \ +	| aarch64-* | aarch64_be-* \  	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \  	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ -	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ +	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \  	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \  	| avr-* | avr32-* \ +	| be32-* | be64-* \  	| bfin-* | bs2000-* \ -	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ -	| clipper-* | craynv-* | cydra-* \ +	| c[123]* | c30-* | [cjt]90-* | c4x-* \ +	| c8051-* | clipper-* | craynv-* | cydra-* \  	| d10v-* | d30v-* | dlx-* \  	| elxsi-* \  	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \  	| h8300-* | h8500-* \  	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ +	| hexagon-* \  	| i*86-* | i860-* | i960-* | ia64-* \  	| ip2k-* | iq2000-* \ +	| le32-* | le64-* \  	| lm32-* \  	| m32c-* | m32r-* | m32rle-* \  	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ -	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ +	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ +	| microblaze-* | microblazeel-* \  	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \  	| mips16-* \  	| mips64-* | mips64el-* \ @@ -363,29 +404,34 @@ case $basic_machine in  	| mipsisa64r2-* | mipsisa64r2el-* \  	| mipsisa64sb1-* | mipsisa64sb1el-* \  	| mipsisa64sr71k-* | mipsisa64sr71kel-* \ +	| mipsr5900-* | mipsr5900el-* \  	| mipstx39-* | mipstx39el-* \  	| mmix-* \  	| mt-* \  	| msp430-* \ -	| nios-* | nios2-* \ +	| nds32-* | nds32le-* | nds32be-* \ +	| nios-* | nios2-* | nios2eb-* | nios2el-* \  	| none-* | np1-* | ns16k-* | ns32k-* \ +	| open8-* \  	| orion-* \  	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ -	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ +	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \  	| pyramid-* \ -	| romp-* | rs6000-* | rx-* \ +	| rl78-* | romp-* | rs6000-* | rx-* \  	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \  	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \  	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \  	| sparclite-* \ -	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ -	| tahoe-* | thumb-* \ -	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ +	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ +	| tahoe-* \ +	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ +	| tile*-* \  	| tron-* \  	| ubicom32-* \ -	| v850-* | v850e-* | vax-* \ +	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ +	| vax-* \  	| we32k-* \ -	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ +	| x86-* | x86_64-* | xc16x-* | xps100-* \  	| xstormy16-* | xtensa*-* \  	| ymp-* \  	| z8k-* | z80-*) @@ -410,7 +456,7 @@ case $basic_machine in  		basic_machine=a29k-amd  		os=-udi  		;; -    	abacus) +	abacus)  		basic_machine=abacus-unknown  		;;  	adobe68k) @@ -480,11 +526,20 @@ case $basic_machine in  		basic_machine=powerpc-ibm  		os=-cnk  		;; +	c54x-*) +		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` +		;; +	c55x-*) +		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` +		;; +	c6x-*) +		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` +		;;  	c90)  		basic_machine=c90-cray  		os=-unicos  		;; -        cegcc) +	cegcc)  		basic_machine=arm-unknown  		os=-cegcc  		;; @@ -516,7 +571,7 @@ case $basic_machine in  		basic_machine=craynv-cray  		os=-unicosmp  		;; -	cr16) +	cr16 | cr16-*)  		basic_machine=cr16-unknown  		os=-elf  		;; @@ -674,7 +729,6 @@ case $basic_machine in  	i370-ibm* | ibm*)  		basic_machine=i370-ibm  		;; -# I'm not sure what "Sysv32" means.  Should this be sysv3.2?  	i*86v32)  		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`  		os=-sysv32 @@ -732,11 +786,15 @@ case $basic_machine in  		basic_machine=ns32k-utek  		os=-sysv  		;; -        microblaze) +	microblaze*)  		basic_machine=microblaze-xilinx  		;; +	mingw64) +		basic_machine=x86_64-pc +		os=-mingw64 +		;;  	mingw32) -		basic_machine=i386-pc +		basic_machine=i686-pc  		os=-mingw32  		;;  	mingw32ce) @@ -771,10 +829,18 @@ case $basic_machine in  	ms1-*)  		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`  		;; +	msys) +		basic_machine=i686-pc +		os=-msys +		;;  	mvs)  		basic_machine=i370-ibm  		os=-mvs  		;; +	nacl) +		basic_machine=le32-unknown +		os=-nacl +		;;  	ncr3000)  		basic_machine=i486-ncr  		os=-sysv4 @@ -839,6 +905,12 @@ case $basic_machine in  	np1)  		basic_machine=np1-gould  		;; +	neo-tandem) +		basic_machine=neo-tandem +		;; +	nse-tandem) +		basic_machine=nse-tandem +		;;  	nsr-tandem)  		basic_machine=nsr-tandem  		;; @@ -921,9 +993,10 @@ case $basic_machine in  		;;  	power)	basic_machine=power-ibm  		;; -	ppc)	basic_machine=powerpc-unknown +	ppc | ppcbe)	basic_machine=powerpc-unknown  		;; -	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` +	ppc-* | ppcbe-*) +		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`  		;;  	ppcle | powerpclittle | ppc-le | powerpc-little)  		basic_machine=powerpcle-unknown @@ -933,7 +1006,7 @@ case $basic_machine in  		;;  	ppc64)	basic_machine=powerpc64-unknown  		;; -	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` +	ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`  		;;  	ppc64le | powerpc64little | ppc64-le | powerpc64-little)  		basic_machine=powerpc64le-unknown @@ -948,7 +1021,11 @@ case $basic_machine in  		basic_machine=i586-unknown  		os=-pw32  		;; -	rdos) +	rdos | rdos64) +		basic_machine=x86_64-pc +		os=-rdos +		;; +	rdos32)  		basic_machine=i386-pc  		os=-rdos  		;; @@ -1017,6 +1094,9 @@ case $basic_machine in  		basic_machine=i860-stratus  		os=-sysv4  		;; +	strongarm-* | thumb-*) +		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` +		;;  	sun2)  		basic_machine=m68000-sun  		;; @@ -1073,20 +1153,8 @@ case $basic_machine in  		basic_machine=t90-cray  		os=-unicos  		;; -	tic54x | c54x*) -		basic_machine=tic54x-unknown -		os=-coff -		;; -	tic55x | c55x*) -		basic_machine=tic55x-unknown -		os=-coff -		;; -	tic6x | c6x*) -		basic_machine=tic6x-unknown -		os=-coff -		;;  	tile*) -		basic_machine=tile-unknown +		basic_machine=$basic_machine-unknown  		os=-linux-gnu  		;;  	tx39) @@ -1156,6 +1224,9 @@ case $basic_machine in  	xps | xps100)  		basic_machine=xps100-honeywell  		;; +	xscale-* | xscalee[bl]-*) +		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` +		;;  	ymp)  		basic_machine=ymp-cray  		os=-unicos @@ -1253,11 +1324,11 @@ esac  if [ x"$os" != x"" ]  then  case $os in -        # First match some system type aliases -        # that might get confused with valid system types. +	# First match some system type aliases +	# that might get confused with valid system types.  	# -solaris* is a basic system type, with this one exception. -        -auroraux) -	        os=-auroraux +	-auroraux) +		os=-auroraux  		;;  	-solaris1 | -solaris1.*)  		os=`echo $os | sed -e 's|solaris1|sunos4|'` @@ -1281,20 +1352,21 @@ case $os in  	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \  	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\  	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ -	      | -sym* | -kopensolaris* \ +	      | -sym* | -kopensolaris* | -plan9* \  	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \  	      | -aos* | -aros* \  	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \  	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \  	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ -	      | -openbsd* | -solidbsd* \ +	      | -bitrig* | -openbsd* | -solidbsd* \  	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \  	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \  	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \  	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \  	      | -chorusos* | -chorusrdb* | -cegcc* \ -	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ -	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ +	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ +	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ +	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \  	      | -uxpv* | -beos* | -mpeix* | -udk* \  	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \  	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ @@ -1341,7 +1413,7 @@ case $os in  	-opened*)  		os=-openedition  		;; -        -os400*) +	-os400*)  		os=-os400  		;;  	-wince*) @@ -1390,7 +1462,7 @@ case $os in  	-sinix*)  		os=-sysv4  		;; -        -tpf*) +	-tpf*)  		os=-tpf  		;;  	-triton*) @@ -1426,15 +1498,14 @@ case $os in  	-aros*)  		os=-aros  		;; -	-kaos*) -		os=-kaos -		;;  	-zvmoe)  		os=-zvmoe  		;;  	-dicos*)  		os=-dicos  		;; +	-nacl*) +		;;  	-none)  		;;  	*) @@ -1457,10 +1528,10 @@ else  # system, and we'll never get to this point.  case $basic_machine in -        score-*) +	score-*)  		os=-elf  		;; -        spu-*) +	spu-*)  		os=-elf  		;;  	*-acorn) @@ -1472,8 +1543,23 @@ case $basic_machine in  	arm*-semi)  		os=-aout  		;; -        c4x-* | tic4x-*) -        	os=-coff +	c4x-* | tic4x-*) +		os=-coff +		;; +	c8051-*) +		os=-elf +		;; +	hexagon-*) +		os=-elf +		;; +	tic54x-*) +		os=-coff +		;; +	tic55x-*) +		os=-coff +		;; +	tic6x-*) +		os=-coff  		;;  	# This must come before the *-dec entry.  	pdp10-*) @@ -1493,14 +1579,11 @@ case $basic_machine in  		;;  	m68000-sun)  		os=-sunos3 -		# This also exists in the configure program, but was not the -		# default. -		# os=-sunos4  		;;  	m68*-cisco)  		os=-aout  		;; -        mep-*) +	mep-*)  		os=-elf  		;;  	mips*-cisco) @@ -1509,6 +1592,9 @@ case $basic_machine in  	mips*-*)  		os=-elf  		;; +	or1k-*) +		os=-elf +		;;  	or32-*)  		os=-coff  		;; @@ -1527,7 +1613,7 @@ case $basic_machine in  	*-ibm)  		os=-aix  		;; -    	*-knuth) +	*-knuth)  		os=-mmixware  		;;  	*-wec) diff --git a/build/linux/configure.ac b/build/linux/configure.ac index d9e1f1a..7c314f3 100644 --- a/build/linux/configure.ac +++ b/build/linux/configure.ac @@ -24,7 +24,7 @@ dnl  dnl -----------------------------------------------------------------------  dnl $Id$ -AC_INIT(astra_toolbox, 1.5.0) +AC_INIT(astra_toolbox, 1.6.0)  AC_CONFIG_SRCDIR([Makefile.in])  LT_INIT([disable-static]) @@ -190,7 +190,7 @@ if test x"$with_python" != x -a x"$with_python" != xno; then    AC_MSG_CHECKING(for python)    ASTRA_RUN_LOGOUTPUT(echo 'import sys' | $PYTHON -)    if test $? -ne 0; then -    AC_MSG_ERROR(Python binary not found)] +    AC_MSG_ERROR(Python binary not found)    fi    AC_MSG_RESULT([$PYTHON])    HAVEPYTHON=yes diff --git a/build/linux/install-sh.dist b/build/linux/install-sh.dist index a5897de..a9244eb 100755 --- a/build/linux/install-sh.dist +++ b/build/linux/install-sh.dist @@ -1,7 +1,7 @@  #!/bin/sh  # install - install a program, script, or datafile -scriptversion=2006-12-25.00 +scriptversion=2011-01-19.21; # UTC  # This originates from X11R5 (mit/util/scripts/install.sh), which was  # later released in X11R6 (xc/config/util/install.sh) with the @@ -156,6 +156,10 @@ while test $# -ne 0; do      -s) stripcmd=$stripprog;;      -t) dst_arg=$2 +	# Protect names problematic for `test' and other utilities. +	case $dst_arg in +	  -* | [=\(\)!]) dst_arg=./$dst_arg;; +	esac  	shift;;      -T) no_target_directory=true;; @@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then      fi      shift # arg      dst_arg=$arg +    # Protect names problematic for `test' and other utilities. +    case $dst_arg in +      -* | [=\(\)!]) dst_arg=./$dst_arg;; +    esac    done  fi @@ -200,7 +208,11 @@ if test $# -eq 0; then  fi  if test -z "$dir_arg"; then -  trap '(exit $?); exit' 1 2 13 15 +  do_exit='(exit $ret); exit $ret' +  trap "ret=129; $do_exit" 1 +  trap "ret=130; $do_exit" 2 +  trap "ret=141; $do_exit" 13 +  trap "ret=143; $do_exit" 15    # Set umask so as not to create temps with too-generous modes.    # However, 'strip' requires both read and write access to temps. @@ -228,9 +240,9 @@ fi  for src  do -  # Protect names starting with `-'. +  # Protect names problematic for `test' and other utilities.    case $src in -    -*) src=./$src;; +    -* | [=\(\)!]) src=./$src;;    esac    if test -n "$dir_arg"; then @@ -252,12 +264,7 @@ do        echo "$0: no destination specified." >&2        exit 1      fi -      dst=$dst_arg -    # Protect names starting with `-'. -    case $dst in -      -*) dst=./$dst;; -    esac      # If destination is a directory, append the input filename; won't work      # if double slashes aren't ignored. @@ -385,7 +392,7 @@ do        case $dstdir in  	/*) prefix='/';; -	-*) prefix='./';; +	[-=\(\)!]*) prefix='./';;  	*)  prefix='';;        esac @@ -403,7 +410,7 @@ do        for d        do -	test -z "$d" && continue +	test X"$d" = X && continue  	prefix=$prefix$d  	if test -d "$prefix"; then @@ -515,5 +522,6 @@ done  # eval: (add-hook 'write-file-hooks 'time-stamp)  # time-stamp-start: "scriptversion="  # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC"  # End: diff --git a/build/msvc/gen.py b/build/msvc/gen.py index 9f5e367..aeca3b0 100644 --- a/build/msvc/gen.py +++ b/build/msvc/gen.py @@ -946,10 +946,11 @@ def write_main_project09():        print('\t\t\t\tRuntime="3"', file=F) # MDD      else:        print('\t\t\t\tRuntime="2"', file=F) # MD +    print('\t\t\t\tExtraCppOptions="-Iinclude -Ilib/include"', file=F)      if c.cuda: -      print('\t\t\t\tDefines="-DASTRA_CUDA -DDLL_EXPORTS"', file=F) +      print('\t\t\t\tDefines="ASTRA_CUDA;DLL_EXPORTS"', file=F)      else: # This 'else' doesn't make much sense -      print('\t\t\t\tDefines="-DDLL_EXPORTS"', file=F) +      print('\t\t\t\tDefines="DLL_EXPORTS"', file=F)      # TODO!!!      print('\t\t\t/>', file=F)      print('\t\t</Configuration>', file=F) diff --git a/include/astra/AstraObjectFactory.h b/include/astra/AstraObjectFactory.h index ba4ec11..1ed4955 100644 --- a/include/astra/AstraObjectFactory.h +++ b/include/astra/AstraObjectFactory.h @@ -110,7 +110,7 @@ template <typename T, typename TypeList>  T* CAstraObjectFactory<T, TypeList>::create(const Config& _cfg)  {  	functor_find<T> finder = functor_find<T>(); -	finder.tofind = _cfg.self->getAttribute("type"); +	finder.tofind = _cfg.self.getAttribute("type");  	CreateObject<TypeList>::find(finder);  	if (finder.res == NULL) return NULL;  	if (finder.res->initialize(_cfg)) diff --git a/include/astra/Config.h b/include/astra/Config.h index 9893c90..c10a16e 100644 --- a/include/astra/Config.h +++ b/include/astra/Config.h @@ -44,13 +44,14 @@ namespace astra {  struct _AstraExport Config {  	Config(); -	Config(XMLNode* _self); +	Config(XMLNode _self);  	~Config();  	void initialize(std::string rootname); -	XMLNode* self; -	XMLNode* global; +	XMLNode self; + +	XMLDocument *_doc;  };  struct ConfigCheckData { diff --git a/include/astra/CudaProjector2D.h b/include/astra/CudaProjector2D.h index a571851..ecfca41 100644 --- a/include/astra/CudaProjector2D.h +++ b/include/astra/CudaProjector2D.h @@ -121,9 +121,15 @@ public:  	virtual std::string description() const; +	Cuda2DProjectionKernel getProjectionKernel() const { return m_projectionKernel; } +	int getVoxelSuperSampling() const { return m_iVoxelSuperSampling; } +	int getDetectorSuperSampling() const { return m_iDetectorSuperSampling; } +  protected:  	Cuda2DProjectionKernel m_projectionKernel; +	int m_iVoxelSuperSampling; +	int m_iDetectorSuperSampling;  };  //---------------------------------------------------------------------------------------- diff --git a/include/astra/CudaProjector3D.h b/include/astra/CudaProjector3D.h index a181531..1d570fe 100644 --- a/include/astra/CudaProjector3D.h +++ b/include/astra/CudaProjector3D.h @@ -115,11 +115,14 @@ public:  	Cuda3DProjectionKernel getProjectionKernel() const { return m_projectionKernel; } +	int getVoxelSuperSampling() const { return m_iVoxelSuperSampling; } +	int getDetectorSuperSampling() const { return m_iDetectorSuperSampling; }  protected:  	Cuda3DProjectionKernel m_projectionKernel; - +	int m_iVoxelSuperSampling; +	int m_iDetectorSuperSampling;  }; diff --git a/include/astra/Globals.h b/include/astra/Globals.h index 9c8ddfb..4de07d1 100644 --- a/include/astra/Globals.h +++ b/include/astra/Globals.h @@ -61,9 +61,9 @@ $Id$  // macro's  #define ASTRA_TOOLBOXVERSION_MAJOR 1 -#define ASTRA_TOOLBOXVERSION_MINOR 5 +#define ASTRA_TOOLBOXVERSION_MINOR 6  #define ASTRA_TOOLBOXVERSION ((ASTRA_TOOLBOXVERSION_MAJOR)*100 + (ASTRA_TOOLBOXVERSION_MINOR)) -#define ASTRA_TOOLBOXVERSION_STRING "1.5" +#define ASTRA_TOOLBOXVERSION_STRING "1.6"  #define ASTRA_ASSERT(a) assert(a) diff --git a/include/astra/XMLDocument.h b/include/astra/XMLDocument.h index 869e1a3..eddd908 100644 --- a/include/astra/XMLDocument.h +++ b/include/astra/XMLDocument.h @@ -78,7 +78,7 @@ public:  	 *  	 * @return first XML node of the document  	 */ -	XMLNode* getRootNode(); +	XMLNode getRootNode();  	/** Save an XML DOM tree to an XML file  	 * diff --git a/include/astra/XMLNode.h b/include/astra/XMLNode.h index eceffe1..4d29d5c 100644 --- a/include/astra/XMLNode.h +++ b/include/astra/XMLNode.h @@ -64,71 +64,68 @@ public:  	/** Deconstructor  	 */  	~XMLNode(); -	 + +	/** Check validity +	 */ +	operator bool() const { return fDOMElement != 0; }  	/** Get a single child XML node. If there are more, the first one is returned  	 *  	 * @param _sName tagname of the requested child node  	 * @return first child node with the correct tagname, null pointer if it doesn't exist  	 */ -	XMLNode* getSingleNode(string _sName); +	XMLNode getSingleNode(string _sName) const;  	/** Get all child XML nodes that have the tagname name  	 *   	 * @param _sName tagname of the requested child nodes  	 * @return list with all child nodes with the correct tagname  	 */ -	std::list<XMLNode*> getNodes(string _sName); +	std::list<XMLNode> getNodes(string _sName) const;  	/** Get all child XML nodes  	 *   	 * @return list with all child nodes   	 */ -	std::list<XMLNode*> getNodes(); +	std::list<XMLNode> getNodes() const;  	/** Get the name of this node  	 *   	 * @return name of node  	 */ -	std::string getName(); +	std::string getName() const;  	/** Get the content of the XML node as a single string.  	 *  	 * @return node content  	 */  -	string getContent(); +	string getContent() const;  	/** Get the content of the XML node as a numerical.  	 *  	 * @return node content  	 */  -	float32 getContentNumerical(); +	float32 getContentNumerical() const;  	/** Get the content of the XML node as a boolean.  	 *  	 * @return node content  	 */  -	bool getContentBool(); +	bool getContentBool() const;  	/** Get the content of the XML node as a vector of strings.  	 *  	 * @return node content  	 */  -	vector<string> getContentArray(); - -	/** Get the content of the XML node as a c-array of float32 data. -	 * -	 * @param _pfData data array, shouldn't be initialized already. -	 * @param _iSize number of elements stored in _pfData -	 */  -	void getContentNumericalArray(float32*& _pfData, int& _iSize); +	vector<string> getContentArray() const;  	/** Get the content of the XML node as a stl container of float32 data. +	 *  NB: A 2D matrix is returned as a linear list  	 *  	 * @return node content  	 */  -	vector<float32> getContentNumericalArray(); -	vector<double> getContentNumericalArrayDouble(); +	vector<float32> getContentNumericalArray() const; +	vector<double> getContentNumericalArrayDouble() const; @@ -137,7 +134,7 @@ public:  	 * @param _sName of the attribute.  	 * @return attribute value, empty string if it doesn't exist.  	 */  -	bool hasAttribute(string _sName); +	bool hasAttribute(string _sName) const;  	/** Get the value of an attribute.  	 * @@ -145,7 +142,7 @@ public:  	 * @param _sDefaultValue value to return if the attribute isn't found  	 * @return attribute value, _sDefaultValue if it doesn't exist.  	 */  -	string getAttribute(string _sName, string _sDefaultValue = ""); +	string getAttribute(string _sName, string _sDefaultValue = "") const;  	/** Get the value of a numerical attribute.  	 * @@ -153,8 +150,8 @@ public:  	 * @param _fDefaultValue value to return if the attribute isn't found  	 * @return attribute value, _fDefaultValue if it doesn't exist.  	 */  -	float32 getAttributeNumerical(string _sName, float32 _fDefaultValue = 0); -	double getAttributeNumericalDouble(string _sName, double _fDefaultValue = 0); +	float32 getAttributeNumerical(string _sName, float32 _fDefaultValue = 0) const; +	double getAttributeNumericalDouble(string _sName, double _fDefaultValue = 0) const;  	/** Get the value of a boolean attribute.  	 * @@ -162,7 +159,7 @@ public:  	 * @param _bDefaultValue value to return if the attribute isn't found  	 * @return attribute value, _bDefaultValue if it doesn't exist.  	 */  -	bool getAttributeBool(string _sName, bool _bDefaultValue = false); +	bool getAttributeBool(string _sName, bool _bDefaultValue = false) const; @@ -172,7 +169,7 @@ public:  	 * @param _sKey option key  	 * @return true if option does exist  	 */  -	bool hasOption(string _sKey); +	bool hasOption(string _sKey) const;  	/** Get the value of an option within this XML Node  	 * @@ -180,7 +177,7 @@ public:  	 * @param _sDefaultValue value to return if key isn't found  	 * @return option value, _sDefaultValue if the option doesn't exist  	 */  -	string getOption(string _sKey, string _sDefaultValue = ""); +	string getOption(string _sKey, string _sDefaultValue = "") const;  	/** Get the value of an option within this XML Node  	 * @@ -188,7 +185,7 @@ public:  	 * @param _fDefaultValue value to return if key isn't found  	 * @return option value, _fDefaultValue if the option doesn't exist  	 */  -	float32 getOptionNumerical(string _sKey, float32 _fDefaultValue = 0); +	float32 getOptionNumerical(string _sKey, float32 _fDefaultValue = 0) const;  	/** Get the value of an option within this XML Node  	 * @@ -196,14 +193,14 @@ public:  	 * @param _bDefaultValue value to return if key isn't found  	 * @return option value, _bDefaultValue if the option doesn't exist  	 */  -	bool getOptionBool(string _sKey, bool _bDefaultValue = false); +	bool getOptionBool(string _sKey, bool _bDefaultValue = false) const;  	/** Get the value of an option within this XML Node  	 *  	 * @param _sKey option key  	 * @return numerical array  	 */  -	vector<float32> getOptionNumericalArray(string _sKey); +	vector<float32> getOptionNumericalArray(string _sKey) const; @@ -214,7 +211,7 @@ public:  	 * @param _sNodeName the name of the new childnode  	 * @return new child node  	 */  -	XMLNode* addChildNode(string _sNodeName); +	XMLNode addChildNode(string _sNodeName);  	/** Create a new XML node as a child to this one, also add some content:   	 * <...><_sNodeName>_sValue</_sNodeName></...> @@ -223,7 +220,7 @@ public:  	 * @param _sValue some node content  	 * @return new child node  	 */  -	XMLNode* addChildNode(string _sNodeName, string _sValue); +	XMLNode addChildNode(string _sNodeName, string _sValue);  	/** Create a new XML node as a child to this one, also add some numerical content:   	 * <...><_sNodeName>_sValue</_sNodeName></...> @@ -232,7 +229,7 @@ public:  	 * @param _fValue some node content  	 * @return new child node  	 */  -	XMLNode* addChildNode(string _sNodeName, float32 _fValue); +	XMLNode addChildNode(string _sNodeName, float32 _fValue);  	/** Create a new XML node as a child to this one, also add a list of numerical content:   	 * <...><_sNodeName>_sValue</_sNodeName></...> @@ -242,7 +239,7 @@ public:  	 * @param _iSize number of elements in _pfList  	 * @return new child node  	 */  -	XMLNode* addChildNode(string _sNodeName, float32* _pfList, int _iSize); +	XMLNode addChildNode(string _sNodeName, float32* _pfList, int _iSize);  	/** Add some text to the node: <...>_sText</...>  	 * @@ -256,13 +253,38 @@ public:  	 */   	void setContent(float32 _fValue); -	/** Add a list of numerical data to the node: <...>_sText</...> +	/** Add a list of numerical data to the node  	 *  	 * @param _pfList data  	 * @param _iSize number of elements in the list  	 */   	void setContent(float32* _pfList, int _iSize); +	/** Add a list of numerical data to the node +	 * +	 * @param _pfList data +	 * @param _iSize number of elements in the list +	 */ +	void setContent(double* _pfList, int _iSize); + +	/** Add a (2D) matrix of numerical data to the node +	 * +	 * @param _pfMatrix data +	 * @param _iWidth width of the matrix +	 * @param _iHeight height of the matrix +	 * @param transposed true is C order, false is Fortran order +	 */ +	void setContent(float32* _pfMatrix, int _iWidth, int _iHeight, bool transposed); + +	/** Add a (2D) matrix of numerical data to the node +	 * +	 * @param _pfMatrix data +	 * @param _iWidth width of the matrix +	 * @param _iHeight height of the matrix +	 * @param transposed true is C order, false is Fortran order +	 */ +	void setContent(double* _pfMatrix, int _iWidth, int _iHeight, bool transposed); +  	/** Add an attribute to this node: <... _sName="_sValue">  	 *  	 * @param _sName name of the attribute @@ -294,11 +316,11 @@ public:  	/** Print to String  	 */ -	std::string toString(); +	std::string toString() const;  	/** Print the node  	 */  -	void print(); +	void print() const;  protected: diff --git a/matlab/mex/astra_mex_algorithm_c.cpp b/matlab/mex/astra_mex_algorithm_c.cpp index e4afa63..ec7aa72 100644 --- a/matlab/mex/astra_mex_algorithm_c.cpp +++ b/matlab/mex/astra_mex_algorithm_c.cpp @@ -81,7 +81,7 @@ void astra_mex_algorithm_create(int nlhs, mxArray* plhs[], int nrhs, const mxArr  	// turn MATLAB struct to an XML-based Config object  	Config* cfg = structToConfig("Algorithm", prhs[1]); -	CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg->self->getAttribute("type")); +	CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg->self.getAttribute("type"));  	if (!pAlg) {  		delete cfg;  		mexErrMsgTxt("Unknown algorithm. \n"); diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp index 4a331f5..a9b9654 100644 --- a/matlab/mex/astra_mex_c.cpp +++ b/matlab/mex/astra_mex_c.cpp @@ -36,9 +36,9 @@ $Id$  #include "mexInitFunctions.h"  #include "astra/Globals.h" - +#ifdef ASTRA_CUDA  #include "../cuda/2d/darthelper.h" - +#endif  using namespace std;  using namespace astra; diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp index 9576896..909d229 100644 --- a/matlab/mex/astra_mex_data2d_c.cpp +++ b/matlab/mex/astra_mex_data2d_c.cpp @@ -149,7 +149,7 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra  		Config* cfg = structToConfig("ProjectionGeometry", prhs[2]);  		// FIXME: Change how the base class is created. (This is duplicated  		// in 'change_geometry' and Projector2D.cpp.) -		std::string type = cfg->self->getAttribute("type"); +		std::string type = cfg->self.getAttribute("type");  		CProjectionGeometry2D* pGeometry;  		if (type == "sparse_matrix") {  			pGeometry = new CSparseMatrixProjectionGeometry2D(); @@ -438,7 +438,7 @@ void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const  		Config* cfg = structToConfig("ProjectionGeometry2D", prhs[2]);  		// FIXME: Change how the base class is created. (This is duplicated  		// in 'create' and Projector2D.cpp.) -		std::string type = cfg->self->getAttribute("type"); +		std::string type = cfg->self.getAttribute("type");  		CProjectionGeometry2D* pGeometry;  		if (type == "sparse_matrix") {  			pGeometry = new CSparseMatrixProjectionGeometry2D(); diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp index 6096adc..fe4ce37 100644 --- a/matlab/mex/astra_mex_data3d_c.cpp +++ b/matlab/mex/astra_mex_data3d_c.cpp @@ -346,7 +346,7 @@ void astra_mex_data3d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const  		astra::Config* cfg = structToConfig("ProjectionGeometry3D", geometry);  		// FIXME: Change how the base class is created. (This is duplicated  		// in Projector3D.cpp.) -		std::string type = cfg->self->getAttribute("type"); +		std::string type = cfg->self.getAttribute("type");  		astra::CProjectionGeometry3D* pGeometry = 0;  		if (type == "parallel3d") {  			pGeometry = new astra::CParallelProjectionGeometry3D(); diff --git a/matlab/mex/astra_mex_log_c.cpp b/matlab/mex/astra_mex_log_c.cpp index ea4621e..905612c 100644 --- a/matlab/mex/astra_mex_log_c.cpp +++ b/matlab/mex/astra_mex_log_c.cpp @@ -55,7 +55,7 @@ void astra_mex_log_debug(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prh  	string filename = mexToString(prhs[1]);  	int linenumber = (int)mxGetScalar(prhs[2]);  	string message = mexToString(prhs[3]); -	astra::CLogger::debug(filename.c_str(),linenumber,message.c_str()); +	astra::CLogger::debug(filename.c_str(),linenumber,"%s",message.c_str());  }  //----------------------------------------------------------------------------------------- @@ -75,7 +75,7 @@ void astra_mex_log_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs  	string filename = mexToString(prhs[1]);  	int linenumber = (int)mxGetScalar(prhs[2]);  	string message = mexToString(prhs[3]); -	astra::CLogger::info(filename.c_str(),linenumber,message.c_str()); +	astra::CLogger::info(filename.c_str(),linenumber,"%s",message.c_str());  }  //----------------------------------------------------------------------------------------- @@ -95,7 +95,7 @@ void astra_mex_log_warn(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs  	string filename = mexToString(prhs[1]);  	int linenumber = (int)mxGetScalar(prhs[2]);  	string message = mexToString(prhs[3]); -	astra::CLogger::warn(filename.c_str(),linenumber,message.c_str()); +	astra::CLogger::warn(filename.c_str(),linenumber,"%s",message.c_str());  }  //----------------------------------------------------------------------------------------- @@ -115,7 +115,7 @@ void astra_mex_log_error(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prh  	string filename = mexToString(prhs[1]);  	int linenumber = (int)mxGetScalar(prhs[2]);  	string message = mexToString(prhs[3]); -	astra::CLogger::error(filename.c_str(),linenumber,message.c_str()); +	astra::CLogger::error(filename.c_str(),linenumber,"%s",message.c_str());  }  //----------------------------------------------------------------------------------------- diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp index c3b547f..e25802c 100644 --- a/matlab/mex/astra_mex_projector3d_c.cpp +++ b/matlab/mex/astra_mex_projector3d_c.cpp @@ -137,7 +137,9 @@ void astra_mex_projector3d_get_projection_geometry(int nlhs, mxArray* plhs[], in  	// step3: get projection_geometry and turn it into a MATLAB struct  	if (1 <= nlhs) { -		plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration()); +		Config *cfg = pProjector->getProjectionGeometry()->getConfiguration(); +		plhs[0] = configToStruct(cfg); +		delete cfg;  	}  } @@ -163,7 +165,9 @@ void astra_mex_projector3d_get_volume_geometry(int nlhs, mxArray* plhs[], int nr  	// step3: get projection_geometry and turn it into a MATLAB struct  	if (1 <= nlhs) { -		plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration()); +		Config *cfg = pProjector->getVolumeGeometry()->getConfiguration(); +		plhs[0] = configToStruct(cfg); +		delete cfg;  	}  } diff --git a/matlab/mex/astra_mex_projector_c.cpp b/matlab/mex/astra_mex_projector_c.cpp index 204ba8e..bf701af 100644 --- a/matlab/mex/astra_mex_projector_c.cpp +++ b/matlab/mex/astra_mex_projector_c.cpp @@ -160,7 +160,9 @@ void astra_mex_projector_projection_geometry(int nlhs, mxArray* plhs[], int nrhs  	// step3: get projection_geometry and turn it into a MATLAB struct  	if (1 <= nlhs) { -		plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration()); +		Config *cfg =  pProjector->getProjectionGeometry()->getConfiguration(); +		plhs[0] = configToStruct(cfg); +		delete cfg;  	}  } @@ -189,8 +191,9 @@ void astra_mex_projector_volume_geometry(int nlhs, mxArray* plhs[], int nrhs, co  	// step3: get projection_geometry and turn it into a MATLAB struct  	if (1 <= nlhs) { -		plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration()); - +		Config *cfg = pProjector->getVolumeGeometry()->getConfiguration(); +		plhs[0] = configToStruct(cfg); +		delete cfg;  	}  } diff --git a/matlab/mex/mexDataManagerHelpFunctions.cpp b/matlab/mex/mexDataManagerHelpFunctions.cpp index d482428..1794abb 100644 --- a/matlab/mex/mexDataManagerHelpFunctions.cpp +++ b/matlab/mex/mexDataManagerHelpFunctions.cpp @@ -285,7 +285,7 @@ allocateDataObject(const std::string & sDataType,  		astra::Config* cfg = structToConfig("ProjectionGeometry3D", geometry);  		// FIXME: Change how the base class is created. (This is duplicated  		// in Projector3D.cpp.) -		std::string type = cfg->self->getAttribute("type"); +		std::string type = cfg->self.getAttribute("type");  		astra::CProjectionGeometry3D* pGeometry = 0;  		if (type == "parallel3d") {  			pGeometry = new astra::CParallelProjectionGeometry3D(); diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp index c0ac711..58e84d2 100644 --- a/matlab/mex/mexHelpFunctions.cpp +++ b/matlab/mex/mexHelpFunctions.cpp @@ -185,7 +185,7 @@ Config* structToConfig(string rootname, const mxArray* pStruct)  }  //----------------------------------------------------------------------------------------- -bool structToXMLNode(XMLNode* node, const mxArray* pStruct)  +bool structToXMLNode(XMLNode node, const mxArray* pStruct)   {  	// loop all fields  	int nfields = mxGetNumberOfFields(pStruct); @@ -199,16 +199,16 @@ bool structToXMLNode(XMLNode* node, const mxArray* pStruct)  		if (mxIsChar(pField)) {  			string sValue = mexToString(pField);  			if (sFieldName == "type") { -				node->addAttribute("type", sValue); +				node.addAttribute("type", sValue);  			} else { -				delete node->addChildNode(sFieldName, sValue); +				node.addChildNode(sFieldName, sValue);  			}  		}  		// scalar  		else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) == 1) {  			string sValue = mexToString(pField); -			delete node->addChildNode(sFieldName, sValue); +			node.addChildNode(sFieldName, sValue);  		}  		// numerical array @@ -217,20 +217,9 @@ bool structToXMLNode(XMLNode* node, const mxArray* pStruct)  				mexErrMsgTxt("Numeric input must be double.");  				return false;  			} -			XMLNode* listbase = node->addChildNode(sFieldName); -			listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); +			XMLNode listbase = node.addChildNode(sFieldName);  			double* pdValues = mxGetPr(pField); -			int index = 0; -			for (unsigned int row = 0; row < mxGetM(pField); row++) { -				for (unsigned int col = 0; col < mxGetN(pField); col++) { -					XMLNode* item = listbase->addChildNode("ListItem"); -					item->addAttribute("index", index); -					item->addAttribute("value", pdValues[col*mxGetM(pField)+row]); -					index++; -					delete item; -				} -			} -			delete listbase; +			listbase.setContent(pdValues, mxGetN(pField), mxGetM(pField), true);  		}  		// not castable to a single string @@ -240,9 +229,8 @@ bool structToXMLNode(XMLNode* node, const mxArray* pStruct)  				if (!ret)  					return false;  			} else { -				XMLNode* newNode = node->addChildNode(sFieldName); +				XMLNode newNode = node.addChildNode(sFieldName);  				bool ret = structToXMLNode(newNode, pField); -				delete newNode;  				if (!ret)  					return false;  			} @@ -254,7 +242,7 @@ bool structToXMLNode(XMLNode* node, const mxArray* pStruct)  }  //-----------------------------------------------------------------------------------------  // Options struct to xml node -bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct) +bool optionsToXMLNode(XMLNode node, const mxArray* pOptionStruct)  {  	// loop all fields  	int nfields = mxGetNumberOfFields(pOptionStruct); @@ -262,7 +250,7 @@ bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct)  		std::string sFieldName = std::string(mxGetFieldNameByNumber(pOptionStruct, i));  		const mxArray* pField = mxGetFieldByNumber(pOptionStruct, 0, i); -		if (node->hasOption(sFieldName)) { +		if (node.hasOption(sFieldName)) {  			mexErrMsgTxt("Duplicate option");  			return false;  		} @@ -270,7 +258,7 @@ bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct)  		// string or scalar  		if (mxIsChar(pField) || mexIsScalar(pField)) {  			string sValue = mexToString(pField); -			node->addOption(sFieldName, sValue); +			node.addOption(sFieldName, sValue);  		}  		// numerical array  		else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) { @@ -279,21 +267,10 @@ bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct)  				return false;  			} -			XMLNode* listbase = node->addChildNode("Option"); -			listbase->addAttribute("key", sFieldName); -			listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); +			XMLNode listbase = node.addChildNode("Option"); +			listbase.addAttribute("key", sFieldName);  			double* pdValues = mxGetPr(pField); -			int index = 0; -			for (unsigned int row = 0; row < mxGetM(pField); row++) { -				for (unsigned int col = 0; col < mxGetN(pField); col++) { -					XMLNode* item = listbase->addChildNode("ListItem"); -					item->addAttribute("index", index); -					item->addAttribute("value", pdValues[col*mxGetM(pField)+row]); -					index++; -					delete item; -				} -			} -			delete listbase; +			listbase.setContent(pdValues, mxGetN(pField), mxGetM(pField), true);  		} else {  			mexErrMsgTxt("Unsupported option type");  			return false; @@ -343,30 +320,33 @@ mxArray* configToStruct(astra::Config* cfg)  }  //----------------------------------------------------------------------------------------- -mxArray* XMLNodeToStruct(astra::XMLNode* node) +mxArray* XMLNodeToStruct(astra::XMLNode node)  {  	std::map<std::string, mxArray*> mList;  	std::map<std::string, mxArray*> mOptions;  	// type_attribute -	if (node->hasAttribute("type")) { -		mList["type"] = mxCreateString(node->getAttribute("type").c_str()); +	if (node.hasAttribute("type")) { +		mList["type"] = mxCreateString(node.getAttribute("type").c_str());  	} -	list<XMLNode*> nodes = node->getNodes(); -	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) { -		XMLNode* subnode = (*it); +	list<XMLNode> nodes = node.getNodes(); +	for (list<XMLNode>::iterator it = nodes.begin(); it != nodes.end(); it++) { +		XMLNode subnode = (*it);  		// option -		if (subnode->getName() == "Option") { -			mOptions[subnode->getAttribute("key")] = stringToMxArray(subnode->getAttribute("value")); +		if (subnode.getName() == "Option") { +			if(subnode.hasAttribute("value")){ +				mOptions[subnode.getAttribute("key")] = stringToMxArray(subnode.getAttribute("value")); +			}else{ +				mOptions[subnode.getAttribute("key")] = stringToMxArray(subnode.getContent()); +			}  		}  		// regular content  		else { -			mList[subnode->getName()] = stringToMxArray(subnode->getContent()); +			mList[subnode.getName()] = stringToMxArray(subnode.getContent());  		} -		delete subnode;  	}  	if (mOptions.size() > 0) mList["options"] = buildStruct(mOptions); diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h index f9ffcf2..3ac5bd8 100644 --- a/matlab/mex/mexHelpFunctions.h +++ b/matlab/mex/mexHelpFunctions.h @@ -58,13 +58,13 @@ mxArray* anyToMxArray(boost::any _any);  // turn a MATLAB struct into a Config object  astra::Config* structToConfig(string rootname, const mxArray* pStruct); -bool structToXMLNode(astra::XMLNode* node, const mxArray* pStruct); -bool optionsToXMLNode(astra::XMLNode* node, const mxArray* pOptionStruct); +bool structToXMLNode(astra::XMLNode node, const mxArray* pStruct); +bool optionsToXMLNode(astra::XMLNode node, const mxArray* pOptionStruct);  std::map<std::string, mxArray*> parseStruct(const mxArray* pInput);  // turn a Config object into a MATLAB struct  mxArray* configToStruct(astra::Config* cfg); -mxArray* XMLNodeToStruct(astra::XMLNode* xml); +mxArray* XMLNodeToStruct(astra::XMLNode xml);  mxArray* stringToMxArray(std::string input);  mxArray* buildStruct(std::map<std::string, mxArray*> mInput); diff --git a/matlab/mex/mexInitFunctions.cpp b/matlab/mex/mexInitFunctions.cpp index d8a50d7..89a31a1 100644 --- a/matlab/mex/mexInitFunctions.cpp +++ b/matlab/mex/mexInitFunctions.cpp @@ -8,7 +8,7 @@ bool mexIsInitialized=false;   *   */  void logCallBack(const char *msg, size_t len){ -    mexPrintf(msg); +    mexPrintf("%s",msg);  }  /** diff --git a/matlab/tools/astra_create_fbp_reconstruction.m b/matlab/tools/astra_create_fbp_reconstruction.m index 5540f27..a2561b7 100644 --- a/matlab/tools/astra_create_fbp_reconstruction.m +++ b/matlab/tools/astra_create_fbp_reconstruction.m @@ -19,6 +19,7 @@ cfg.ProjectorId = proj_id;  cfg.Options.GPUindex = 0;  alg_id = astra_mex_algorithm('create', cfg);  astra_mex_algorithm('run', alg_id); +astra_mex_algorithm('delete', alg_id);  if numel(sinogram) ~= 1  	astra_mex_data2d('delete', sinogram_id); diff --git a/matlab/tools/astra_create_reconstruction_cuda.m b/matlab/tools/astra_create_reconstruction_cuda.m index 7d9e1dd..7d0421c 100644 --- a/matlab/tools/astra_create_reconstruction_cuda.m +++ b/matlab/tools/astra_create_reconstruction_cuda.m @@ -45,7 +45,7 @@ if strcmp(rec_type,'')  end  % configure -cfg = astra_struct('SIRT_CUDA'); +cfg = astra_struct(rec_type);  cfg.ProjectionGeometry = proj_geom;  cfg.ReconstructionGeometry = vol_geom;  cfg.ProjectionDataId = sinogram_id; diff --git a/matlab/tools/opTomo.m b/matlab/tools/opTomo.m new file mode 100644 index 0000000..14128d2 --- /dev/null +++ b/matlab/tools/opTomo.m @@ -0,0 +1,280 @@ +%OPTOMO Wrapper for ASTRA tomography projector +% +%   OP = OPTOMO(TYPE, PROJ_GEOM, VOL_GEOM) generates a Spot operator OP for +%   the ASTRA forward and backprojection operations. The string TYPE +%   determines the model used for the projections. Possible choices are: +%       TYPE:  * using the CPU +%                'line'   - use a line kernel +%                'linear' - use a Joseph kernel +%                'strip'  - use the strip kernel +%              * using the GPU +%                'cuda'  - use a Joseph kernel, on the GPU, currently using +%                          'cuda' is the only option in 3D. +%   The PROJ_GEOM and VOL_GEOM structures are projection and volume +%   geometries as used in the ASTRA toolbox. +% +%   OP = OPTOMO(TYPE, PROJ_GEOM, VOL_GEOM, GPU_INDEX) also specify the +%   index of the GPU that should be used, if multiple GPUs are present in +%   the host system. By default GPU_INDEX is 0. +% +%   Note: this code depends on the Matlab toolbox  +%   "Spot - A Linear-Operator Toolbox" which can be downloaded from +%   http://www.cs.ubc.ca/labs/scl/spot/ +%-------------------------------------------------------------------------- +% This file is part of the ASTRA Toolbox +%  +% Copyright: 2014-2015, CWI, Amsterdam +% License:   Open Source under GPLv3 +% Author:    Folkert Bleichrodt +% Contact:   F.Bleichrodt@cwi.nl +% Website:   http://sf.net/projects/astra-toolbox +%-------------------------------------------------------------------------- +% $Id$ + +classdef opTomo < opSpot +     +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +    % Properties +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +    properties ( Access = private ) +        % multiplication function +        funHandle +        % ASTRA identifiers +        sino_id +        vol_id +        fp_alg_id +        bp_alg_id +        % ASTRA IDs handle +        astra_handle +        % geometries +        proj_geom; +        vol_geom; +    end % properties +     +    properties ( SetAccess = private, GetAccess = public ) +        proj_size +        vol_size +    end % properties +     +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +    % Methods - public +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +    methods + +        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +        % opTomo - constructor +        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +        function op = opTomo(type, proj_geom, vol_geom, gpu_index) +             +            if nargin < 4 || isempty(gpu_index), gpu_index = 0; end +             +            proj_size = astra_geom_size(proj_geom); +            vol_size  = astra_geom_size(vol_geom); +             +            % construct operator +            op = op@opSpot('opTomo', prod(proj_size), prod(vol_size)); +             +            % determine the dimension +            is2D = ~isfield(vol_geom, 'GridSliceCount'); +            gpuEnabled = strcmpi(type, 'cuda'); +             +            if is2D +                % create a projector +                proj_id = astra_create_projector(type, proj_geom, vol_geom); +                 +                % create a function handle +                op.funHandle = @opTomo_intrnl2D; +                 +                % Initialize ASTRA data objects. +                % projection data +                sino_id = astra_mex_data2d('create', '-sino', proj_geom, 0); +                % image data +                vol_id  = astra_mex_data2d('create', '-vol', vol_geom, 0); +                 +                % Setup forward and back projection algorithms. +                if gpuEnabled +                    fp_alg = 'FP_CUDA'; +                    bp_alg = 'BP_CUDA'; +                    proj_id = []; +                else +                    fp_alg = 'FP'; +                    bp_alg = 'BP'; +                    proj_id = astra_create_projector(type, proj_geom, vol_geom); +                end +                 +                % configuration for ASTRA fp algorithm +                cfg_fp = astra_struct(fp_alg); +                cfg_fp.ProjectorId      = proj_id; +                cfg_fp.ProjectionDataId = sino_id; +                cfg_fp.VolumeDataId     = vol_id; +                 +                % configuration for ASTRA bp algorithm +                cfg_bp = astra_struct(bp_alg); +                cfg_bp.ProjectionDataId     = sino_id; +                cfg_bp.ProjectorId          = proj_id; +                cfg_bp.ReconstructionDataId = vol_id; +                 +                % set GPU index +                if gpuEnabled +                    cfg_fp.option.GPUindex = gpu_index; +                    cfg_bp.option.GPUindex = gpu_index; +                end +                 +                fp_alg_id = astra_mex_algorithm('create', cfg_fp); +                bp_alg_id = astra_mex_algorithm('create', cfg_bp); +                 +                % Create handle to ASTRA objects, so they will be deleted +                % if opTomo is deleted. +                op.astra_handle = opTomo_helper_handle([sino_id, ... +                    vol_id, proj_id, fp_alg_id, bp_alg_id]); +                 +                op.fp_alg_id   = fp_alg_id; +                op.bp_alg_id   = bp_alg_id; +                op.sino_id     = sino_id; +                op.vol_id      = vol_id; +            else +                % 3D +                % only gpu/cuda code for 3D +                if ~gpuEnabled +                    error(['Only type ' 39 'cuda' 39 ' is supported ' ... +                           'for 3D geometries.']) +                end +                 +                % create a function handle +                op.funHandle = @opTomo_intrnl3D; +            end +       +             +            % pass object properties +            op.proj_size   = proj_size; +            op.vol_size    = vol_size; +            op.proj_geom   = proj_geom; +            op.vol_geom    = vol_geom; +            op.cflag       = false; +            op.sweepflag   = false; + +        end % opTomo - constructor +         +    end % methods - public + +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +    % Methods - protected +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +    methods( Access = protected ) + +        % multiplication +        function y = multiply(op,x,mode) +             +            % ASTRA cannot handle sparse vectors +            if issparse(x) +                x = full(x); +            end +             +            % convert input to single +            if isa(x, 'single') == false +                x = single(x); +            end +             +            % the multiplication +            y = op.funHandle(op, x, mode); +             +            % make sure output is column vector +            y = y(:); +             +        end % multiply +         +    end % methods - protected +     +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +    % Methods - private +    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +    methods( Access = private ) +         +        % 2D projection code +        function y = opTomo_intrnl2D(op,x,mode) +                        +            if mode == 1               +                % X is passed as a vector, reshape it into an image.              +                x = reshape(x, op.vol_size); +                 +                % Matlab data copied to ASTRA data +                astra_mex_data2d('store', op.vol_id, x); +                 +                % forward projection +                astra_mex_algorithm('iterate', op.fp_alg_id); +                 +                % retrieve Matlab array +                y = astra_mex_data2d('get_single', op.sino_id); +            else +                % X is passed as a vector, reshape it into a sinogram. +                x = reshape(x, op.proj_size); +                 +                % Matlab data copied to ASTRA data +                astra_mex_data2d('store', op.sino_id, x); +                 +                % backprojection +                astra_mex_algorithm('iterate', op.bp_alg_id); +                 +                % retrieve Matlab array +                y = astra_mex_data2d('get_single', op.vol_id); +            end +        end % opTomo_intrnl2D +         +         +        % 3D projection code +        function y = opTomo_intrnl3D(op,x,mode) +             +            if mode == 1 +                % X is passed as a vector, reshape it into an image +                x = reshape(x, op.vol_size); +                 +                % initialize output +                y = zeros(op.proj_size, 'single'); +                 +                % link matlab array to ASTRA +                vol_id  = astra_mex_data3d_c('link', '-vol', op.vol_geom, x, 0); +                sino_id = astra_mex_data3d_c('link', '-sino', op.proj_geom, y, 1); +                 +                % initialize fp algorithm +                cfg = astra_struct('FP3D_CUDA'); +                cfg.ProjectionDataId = sino_id; +                cfg.VolumeDataId     = vol_id; +                 +                alg_id = astra_mex_algorithm('create', cfg); +                              +                % forward projection +                astra_mex_algorithm('iterate', alg_id); +                 +                % cleanup +                astra_mex_data3d('delete', vol_id); +                astra_mex_data3d('delete', sino_id); +            else +                % X is passed as a vector, reshape it into projection data +                x = reshape(x, op.proj_size); +                 +                % initialize output +                y = zeros(op.vol_size,'single'); +                 +                % link matlab array to ASTRA +                vol_id  = astra_mex_data3d_c('link', '-vol', op.vol_geom, y, 1); +                sino_id = astra_mex_data3d_c('link', '-sino', op.proj_geom, x, 0); +                                 +                % initialize bp algorithm +                cfg = astra_struct('BP3D_CUDA'); +                cfg.ProjectionDataId     = sino_id; +                cfg.ReconstructionDataId = vol_id; +                 +                alg_id = astra_mex_algorithm('create', cfg); + +                % backprojection +                astra_mex_algorithm('iterate', alg_id); +                 +                % cleanup +                astra_mex_data3d('delete', vol_id); +                astra_mex_data3d('delete', sino_id); +            end  +        end % opTomo_intrnl3D +         +    end % methods - private +  +end % classdef diff --git a/matlab/tools/opTomo_helper_handle.m b/matlab/tools/opTomo_helper_handle.m new file mode 100644 index 0000000..d9be51f --- /dev/null +++ b/matlab/tools/opTomo_helper_handle.m @@ -0,0 +1,29 @@ +classdef opTomo_helper_handle < handle +    %ASTRA.OPTOMO_HELPER_HANDLE Handle class around an astra identifier +    %   Automatically deletes the data when object is deleted.  +    %   Multiple id's can be passed as an array as input to  +    %   the constructor. +     +    properties +        id +    end +     +    methods +        function obj = opTomo_helper_handle(id) +            obj.id = id; +        end +        function delete(obj) +            for i = 1:numel(obj.id) +                % delete any kind of object +                astra_mex_data2d('delete', obj.id(i)); +                astra_mex_data3d('delete', obj.id(i)); +                astra_mex_algorithm('delete', obj.id(i)); +                astra_mex_matrix('delete', obj.id(i)); +                astra_mex_projector('delete', obj.id(i)); +                astra_mex_projector3d('delete', obj.id(i)) +            end +        end +    end +     +end + diff --git a/python/astra/ASTRAProjector.py b/python/astra/ASTRAProjector.py deleted file mode 100644 index f282618..0000000 --- a/python/astra/ASTRAProjector.py +++ /dev/null @@ -1,135 +0,0 @@ -#----------------------------------------------------------------------- -#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam -# -#Author: Daniel M. Pelt -#Contact: D.M.Pelt@cwi.nl -#Website: http://dmpelt.github.io/pyastratoolbox/ -# -# -#This file is part of the Python interface to the -#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). -# -#The Python interface to the ASTRA Toolbox is free software: you can redistribute it and/or modify -#it under the terms of the GNU General Public License as published by -#the Free Software Foundation, either version 3 of the License, or -#(at your option) any later version. -# -#The Python interface to the ASTRA Toolbox is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. -# -#You should have received a copy of the GNU General Public License -#along with the Python interface to the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. -# -#----------------------------------------------------------------------- - -import math -from . import creators as ac -from . import data2d - - -class ASTRAProjector2DTranspose(): -    """Implements the ``proj.T`` functionality. - -    Do not use directly, since it can be accessed as member ``.T`` of -    an :class:`ASTRAProjector2D` object. - -    """ -    def __init__(self, parentProj): -        self.parentProj = parentProj - -    def __mul__(self, data): -        return self.parentProj.backProject(data) - - -class ASTRAProjector2D(object): -    """Helps with various common ASTRA Toolbox 2D operations. - -    This class can perform several often used toolbox operations, such as: - -    * Forward projecting -    * Back projecting -    * Reconstructing - -    Note that this class has a some computational overhead, because it -    copies a lot of data. If you use many repeated operations, directly -    using the PyAstraToolbox methods directly is faster. - -    You can use this class as an abstracted weight matrix :math:`W`: multiplying an instance -    ``proj`` of this class by an image results in a forward projection of the image, and multiplying -    ``proj.T`` by a sinogram results in a backprojection of the sinogram:: - -        proj = ASTRAProjector2D(...) -        fp = proj*image -        bp = proj.T*sinogram - -    :param proj_geom: The projection geometry. -    :type proj_geom: :class:`dict` -    :param vol_geom: The volume geometry. -    :type vol_geom: :class:`dict` -    :param proj_type: Projector type, such as ``'line'``, ``'linear'``, ... -    :type proj_type: :class:`string` -    """ - -    def __init__(self, proj_geom, vol_geom, proj_type): -        self.vol_geom = vol_geom -        self.recSize = vol_geom['GridColCount'] -        self.angles = proj_geom['ProjectionAngles'] -        self.nDet = proj_geom['DetectorCount'] -        nexpow = int(pow(2, math.ceil(math.log(2 * self.nDet, 2)))) -        self.filterSize = nexpow / 2 + 1 -        self.nProj = self.angles.shape[0] -        self.proj_geom = proj_geom -        self.proj_id = ac.create_projector(proj_type, proj_geom, vol_geom) -        self.T = ASTRAProjector2DTranspose(self) - -    def backProject(self, data): -        """Backproject a sinogram. - -        :param data: The sinogram data or ID. -        :type data: :class:`numpy.ndarray` or :class:`int` -        :returns: :class:`numpy.ndarray` -- The backprojection. - -        """ -        vol_id, vol = ac.create_backprojection( -            data, self.proj_id, returnData=True) -        data2d.delete(vol_id) -        return vol - -    def forwardProject(self, data): -        """Forward project an image. - -        :param data: The image data or ID. -        :type data: :class:`numpy.ndarray` or :class:`int` -        :returns: :class:`numpy.ndarray` -- The forward projection. - -        """ -        sin_id, sino = ac.create_sino(data, self.proj_id, returnData=True) -        data2d.delete(sin_id) -        return sino - -    def reconstruct(self, data, method, **kwargs): -        """Reconstruct an image from a sinogram. - -        :param data: The sinogram data or ID. -        :type data: :class:`numpy.ndarray` or :class:`int` -        :param method: Name of the reconstruction algorithm. -        :type method: :class:`string` -        :param kwargs: Additional named parameters to pass to :func:`astra.creators.create_reconstruction`. -        :returns: :class:`numpy.ndarray` -- The reconstruction. - -        Example of a SIRT reconstruction using CUDA:: - -            proj = ASTRAProjector2D(...) -            rec = proj.reconstruct(sinogram,'SIRT_CUDA',iterations=1000) - -        """ -        kwargs['returnData'] = True -        rec_id, rec = ac.create_reconstruction( -            method, self.proj_id, data, **kwargs) -        data2d.delete(rec_id) -        return rec - -    def __mul__(self, data): -        return self.forwardProject(data) diff --git a/python/astra/PyIncludes.pxd b/python/astra/PyIncludes.pxd index 1d8285b..35dea5f 100644 --- a/python/astra/PyIncludes.pxd +++ b/python/astra/PyIncludes.pxd @@ -43,7 +43,7 @@ cdef extern from "astra/Config.h" namespace "astra":  	cdef cppclass Config:  		Config()  		void initialize(string rootname) -		XMLNode *self +		XMLNode self  cdef extern from "astra/VolumeGeometry2D.h" namespace "astra":  	cdef cppclass CVolumeGeometry2D: @@ -143,7 +143,7 @@ cdef extern from "astra/Float32ProjectionData2D.h" namespace "astra":  cdef extern from "astra/Algorithm.h" namespace "astra":  	cdef cppclass CAlgorithm:  		bool initialize(Config) -		void run(int) +		void run(int) nogil  		bool isInitialized()  cdef extern from "astra/ReconstructionAlgorithm2D.h" namespace "astra": diff --git a/python/astra/PyXMLDocument.pxd b/python/astra/PyXMLDocument.pxd index 69781f1..033b8ef 100644 --- a/python/astra/PyXMLDocument.pxd +++ b/python/astra/PyXMLDocument.pxd @@ -44,22 +44,24 @@ cdef extern from "astra/Globals.h" namespace "astra":  cdef extern from "astra/XMLNode.h" namespace "astra":      cdef cppclass XMLNode:          string getName() -        XMLNode *addChildNode(string name) -        XMLNode *addChildNode(string, string) +        XMLNode addChildNode(string name) +        XMLNode addChildNode(string, string)          void addAttribute(string, string)          void addAttribute(string, float32)          void addOption(string, string)          bool hasOption(string)          string getAttribute(string) -        list[XMLNode *] getNodes() +        list[XMLNode] getNodes()          vector[float32] getContentNumericalArray() +        void setContent(double*, int, int, bool) +        void setContent(double*, int)          string getContent()          bool hasAttribute(string)  cdef extern from "astra/XMLDocument.h" namespace "astra":      cdef cppclass XMLDocument:          void saveToFile(string sFilename) -        XMLNode *getRootNode() +        XMLNode getRootNode()  cdef extern from "astra/XMLDocument.h" namespace "astra::XMLDocument":      cdef XMLDocument *createDocument(string rootname) diff --git a/python/astra/__init__.py b/python/astra/__init__.py index 063dc16..6c15d30 100644 --- a/python/astra/__init__.py +++ b/python/astra/__init__.py @@ -27,7 +27,6 @@ from . import matlab as m  from .creators import astra_dict,create_vol_geom, create_proj_geom, create_backprojection, create_sino, create_reconstruction, create_projector,create_sino3d_gpu, create_backprojection3d_gpu  from .functions import data_op, add_noise_to_sino, clear, move_vol_geom  from .extrautils import clipCircle -from .ASTRAProjector import ASTRAProjector2D  from . import data2d  from . import astra  from . import data3d @@ -36,6 +35,7 @@ from . import projector  from . import projector3d  from . import matrix  from . import log +from .optomo import OpTomo  import os  try: diff --git a/python/astra/algorithm_c.pyx b/python/astra/algorithm_c.pyx index 966d3d7..3231c1f 100644 --- a/python/astra/algorithm_c.pyx +++ b/python/astra/algorithm_c.pyx @@ -73,7 +73,9 @@ cdef CAlgorithm * getAlg(i) except NULL:  def run(i, iterations=0):      cdef CAlgorithm * alg = getAlg(i) -    alg.run(iterations) +    cdef int its = iterations +    with nogil: +        alg.run(its)  def get_res_norm(i): diff --git a/python/astra/data2d_c.pyx b/python/astra/data2d_c.pyx index ac54898..4919bf2 100644 --- a/python/astra/data2d_c.pyx +++ b/python/astra/data2d_c.pyx @@ -47,6 +47,12 @@ from .PyIncludes cimport *  cimport utils  from .utils import wrap_from_bytes +from .pythonutils import geom_size + +import operator + +from six.moves import reduce +  cdef CData2DManager * man2d = <CData2DManager * >PyData2DManager.getSingletonPtr()  cdef extern from "CFloat32CustomPython.h": @@ -71,6 +77,10 @@ def create(datatype, geometry, data=None, link=False):      cdef CProjectionGeometry2D * ppGeometry      cdef CFloat32Data2D * pDataObject2D      cdef CFloat32CustomMemory * pCustom + +    if link and data.shape!=geom_size(geometry): +        raise Exception("The dimensions of the data do not match those specified in the geometry.") +      if datatype == '-vol':          cfg = utils.dictToConfig(six.b('VolumeGeometry'), geometry)          pGeometry = new CVolumeGeometry2D() diff --git a/python/astra/data3d_c.pyx b/python/astra/data3d_c.pyx index 84472c1..3b27ab7 100644 --- a/python/astra/data3d_c.pyx +++ b/python/astra/data3d_c.pyx @@ -45,6 +45,13 @@ from .PyXMLDocument cimport XMLDocument  cimport utils  from .utils import wrap_from_bytes +from .pythonutils import geom_size + +import operator + +from six.moves import reduce + +  cdef CData3DManager * man3d = <CData3DManager * >PyData3DManager.getSingletonPtr()  cdef extern from *: @@ -61,6 +68,10 @@ def create(datatype,geometry,data=None, link=False):      cdef CFloat32Data3DMemory * pDataObject3D      cdef CConeProjectionGeometry3D* pppGeometry      cdef CFloat32CustomMemory * pCustom + +    if link and data.shape!=geom_size(geometry): +        raise Exception("The dimensions of the data do not match those specified in the geometry.") +      if datatype == '-vol':          cfg = utils.dictToConfig(six.b('VolumeGeometry'), geometry)          pGeometry = new CVolumeGeometry3D() diff --git a/python/astra/functions.py b/python/astra/functions.py index 4025468..e38b5bc 100644 --- a/python/astra/functions.py +++ b/python/astra/functions.py @@ -32,12 +32,17 @@  from . import creators as ac  import numpy as np -from six.moves import range +try: +    from six.moves import range +except ImportError: +    # six 1.3.0 +    from six.moves import xrange as range  from . import data2d  from . import data3d  from . import projector  from . import algorithm +from . import pythonutils @@ -158,29 +163,7 @@ def geom_size(geom, dim=None):      :param dim: Optional axis index to return      :type dim: :class:`int`      """ - -    if 'GridSliceCount' in geom: -        # 3D Volume geometry? -        s = (geom['GridSliceCount'], geom[ -             'GridRowCount'], geom['GridColCount']) -    elif 'GridColCount' in geom: -        # 2D Volume geometry? -        s = (geom['GridRowCount'], geom['GridColCount']) -    elif geom['type'] == 'parallel' or geom['type'] == 'fanflat': -        s = (len(geom['ProjectionAngles']), geom['DetectorCount']) -    elif geom['type'] == 'parallel3d' or geom['type'] == 'cone': -        s = (geom['DetectorRowCount'], len( -            geom['ProjectionAngles']), geom['DetectorColCount']) -    elif geom['type'] == 'fanflat_vec': -        s = (geom['Vectors'].shape[0], geom['DetectorCount']) -    elif geom['type'] == 'parallel3d_vec' or geom['type'] == 'cone_vec': -        s = (geom['DetectorRowCount'], geom[ -             'Vectors'].shape[0], geom['DetectorColCount']) - -    if dim != None: -        s = s[dim] - -    return s +    return pythonutils.geom_size(geom,dim)  def geom_2vec(proj_geom): diff --git a/python/astra/log_c.pyx b/python/astra/log_c.pyx index 969cc06..55c63e6 100644 --- a/python/astra/log_c.pyx +++ b/python/astra/log_c.pyx @@ -52,16 +52,20 @@ cdef extern from "astra/Logging.h" namespace "astra::CLogger":      void setFormatScreen(const char *fmt)  def log_debug(sfile, sline, message): -    debug(six.b(sfile),sline,six.b(message)) +    cstr = list(map(six.b,(sfile,message))) +    debug(cstr[0],sline,"%s",<char*>cstr[1])  def log_info(sfile, sline, message): -    info(six.b(sfile),sline,six.b(message)) +    cstr = list(map(six.b,(sfile,message))) +    info(cstr[0],sline,"%s",<char*>cstr[1])  def log_warn(sfile, sline, message): -    warn(six.b(sfile),sline,six.b(message)) +    cstr = list(map(six.b,(sfile,message))) +    warn(cstr[0],sline,"%s",<char*>cstr[1])  def log_error(sfile, sline, message): -    error(six.b(sfile),sline,six.b(message)) +    cstr = list(map(six.b,(sfile,message))) +    error(cstr[0],sline,"%s",<char*>cstr[1])  def log_enable():      enable() @@ -82,10 +86,12 @@ def log_disableFile():      disableFile()  def log_setFormatFile(fmt): -    setFormatFile(six.b(fmt)) +    cstr = six.b(fmt) +    setFormatFile(cstr)  def log_setFormatScreen(fmt): -    setFormatScreen(six.b(fmt)) +    cstr = six.b(fmt) +    setFormatScreen(cstr)  enumList = [LOG_DEBUG,LOG_INFO,LOG_WARN,LOG_ERROR] @@ -93,4 +99,5 @@ def log_setOutputScreen(fd, level):      setOutputScreen(fd, enumList[level])  def log_setOutputFile(filename, level): -    setOutputFile(six.b(filename), enumList[level])
\ No newline at end of file +    cstr = six.b(filename) +    setOutputFile(cstr, enumList[level]) diff --git a/python/astra/matrix_c.pyx b/python/astra/matrix_c.pyx index b0d8bc4..d099a75 100644 --- a/python/astra/matrix_c.pyx +++ b/python/astra/matrix_c.pyx @@ -27,7 +27,12 @@  # distutils: libraries = astra  import six -from six.moves import range +try: +    from six.moves import range +except ImportError: +    # six 1.3.0 +    from six.moves import xrange as range +  import numpy as np  import scipy.sparse as ss diff --git a/python/astra/optomo.py b/python/astra/optomo.py new file mode 100644 index 0000000..4a64150 --- /dev/null +++ b/python/astra/optomo.py @@ -0,0 +1,219 @@ +#----------------------------------------------------------------------- +#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam +# +#Author: Daniel M. Pelt +#Contact: D.M.Pelt@cwi.nl +#Website: http://dmpelt.github.io/pyastratoolbox/ +# +# +#This file is part of the Python interface to the +#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). +# +#The Python interface to the ASTRA Toolbox is free software: you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +# +#The Python interface to the ASTRA Toolbox is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. +# +#You should have received a copy of the GNU General Public License +#along with the Python interface to the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. +# +#----------------------------------------------------------------------- + +from . import data2d +from . import data3d +from . import projector +from . import projector3d +from . import creators +from . import algorithm +from . import functions +import numpy as np +from six.moves import reduce +try: +    from six.moves import range +except ImportError: +    # six 1.3.0 +    from six.moves import xrange as range + +import operator +import scipy.sparse.linalg + +class OpTomo(scipy.sparse.linalg.LinearOperator): +    """Object that imitates a projection matrix with a given projector. + +    This object can do forward projection by using the ``*`` operator:: + +        W = astra.OpTomo(proj_id) +        fp = W*image +        bp = W.T*sinogram + +    It can also be used in minimization methods of the :mod:`scipy.sparse.linalg` module:: + +        W = astra.OpTomo(proj_id) +        output = scipy.sparse.linalg.lsqr(W,sinogram) + +    :param proj_id: ID to a projector. +    :type proj_id: :class:`int` +    """ + +    def __init__(self,proj_id): +        self.dtype = np.float32 +        try: +            self.vg = projector.volume_geometry(proj_id) +            self.pg = projector.projection_geometry(proj_id) +            self.data_mod = data2d +            self.appendString = "" +            if projector.is_cuda(proj_id): +                self.appendString += "_CUDA" +        except Exception: +            self.vg = projector3d.volume_geometry(proj_id) +            self.pg = projector3d.projection_geometry(proj_id) +            self.data_mod = data3d +            self.appendString = "3D" +            if projector3d.is_cuda(proj_id): +                self.appendString += "_CUDA" + +        self.vshape = functions.geom_size(self.vg) +        self.vsize = reduce(operator.mul,self.vshape) +        self.sshape = functions.geom_size(self.pg) +        self.ssize = reduce(operator.mul,self.sshape) + +        self.shape = (self.ssize, self.vsize) + +        self.proj_id = proj_id + +        self.transposeOpTomo = OpTomoTranspose(self) +        try: +            self.T = self.transposeOpTomo +        except AttributeError: +            # Scipy >= 0.16 defines self.T using self._transpose() +            pass + +    def _transpose(self): +        return self.transposeOpTomo + +    def __checkArray(self, arr, shp): +        if len(arr.shape)==1: +            arr = arr.reshape(shp) +        if arr.dtype != np.float32: +            arr = arr.astype(np.float32) +        if arr.flags['C_CONTIGUOUS']==False: +            arr = np.ascontiguousarray(arr) +        return arr + +    def _matvec(self,v): +        """Implements the forward operator. + +        :param v: Volume to forward project. +        :type v: :class:`numpy.ndarray` +        """ +        v = self.__checkArray(v, self.vshape) +        vid = self.data_mod.link('-vol',self.vg,v) +        s = np.zeros(self.sshape,dtype=np.float32) +        sid = self.data_mod.link('-sino',self.pg,s) + +        cfg = creators.astra_dict('FP'+self.appendString) +        cfg['ProjectionDataId'] = sid +        cfg['VolumeDataId'] = vid +        cfg['ProjectorId'] = self.proj_id +        fp_id = algorithm.create(cfg) +        algorithm.run(fp_id) + +        algorithm.delete(fp_id) +        self.data_mod.delete([vid,sid]) +        return s.flatten() + +    def rmatvec(self,s): +        """Implements the transpose operator. + +        :param s: The projection data. +        :type s: :class:`numpy.ndarray` +        """ +        s = self.__checkArray(s, self.sshape) +        sid = self.data_mod.link('-sino',self.pg,s) +        v = np.zeros(self.vshape,dtype=np.float32) +        vid = self.data_mod.link('-vol',self.vg,v) + +        cfg = creators.astra_dict('BP'+self.appendString) +        cfg['ProjectionDataId'] = sid +        cfg['ReconstructionDataId'] = vid +        cfg['ProjectorId'] = self.proj_id +        bp_id = algorithm.create(cfg) +        algorithm.run(bp_id) + +        algorithm.delete(bp_id) +        self.data_mod.delete([vid,sid]) +        return v.flatten() + +    def __mul__(self,v): +        """Provides easy forward operator by *. + +        :param v: Volume to forward project. +        :type v: :class:`numpy.ndarray` +        """ +        # Catch the case of a forward projection of a 2D/3D image +        if isinstance(v, np.ndarray) and v.shape==self.vshape: +            return self._matvec(v) +        return scipy.sparse.linalg.LinearOperator.__mul__(self, v) + +    def reconstruct(self, method, s, iterations=1, extraOptions = {}): +        """Reconstruct an object. + +        :param method: Method to use for reconstruction. +        :type method: :class:`string` +        :param s: The projection data. +        :type s: :class:`numpy.ndarray` +        :param iterations: Number of iterations to use. +        :type iterations: :class:`int` +        :param extraOptions: Extra options to use during reconstruction (i.e. for cfg['option']). +        :type extraOptions: :class:`dict` +        """ +        s = self.__checkArray(s, self.sshape) +        sid = self.data_mod.link('-sino',self.pg,s) +        v = np.zeros(self.vshape,dtype=np.float32) +        vid = self.data_mod.link('-vol',self.vg,v) +        cfg = creators.astra_dict(method) +        cfg['ProjectionDataId'] = sid +        cfg['ReconstructionDataId'] = vid +        cfg['ProjectorId'] = self.proj_id +        cfg['option'] = extraOptions +        alg_id = algorithm.create(cfg) +        algorithm.run(alg_id,iterations) +        algorithm.delete(alg_id) +        self.data_mod.delete([vid,sid]) +        return v + +class OpTomoTranspose(scipy.sparse.linalg.LinearOperator): +    """This object provides the transpose operation (``.T``) of the OpTomo object. + +    Do not use directly, since it can be accessed as member ``.T`` of +    an :class:`OpTomo` object. +    """ +    def __init__(self,parent): +        self.parent = parent +        self.dtype = np.float32 +        self.shape = (parent.shape[1], parent.shape[0]) +        try: +            self.T = self.parent +        except AttributeError: +            # Scipy >= 0.16 defines self.T using self._transpose() +            pass + +    def _matvec(self, s): +        return self.parent.rmatvec(s) + +    def rmatvec(self, v): +        return self.parent.matvec(v) + +    def _transpose(self): +        return self.parent + +    def __mul__(self,s): +        # Catch the case of a backprojection of 2D/3D data +        if isinstance(s, np.ndarray) and s.shape==self.parent.sshape: +            return self._matvec(s) +        return scipy.sparse.linalg.LinearOperator.__mul__(self, s) diff --git a/python/astra/projector3d_c.pyx b/python/astra/projector3d_c.pyx index 8b978d7..aec9cde 100644 --- a/python/astra/projector3d_c.pyx +++ b/python/astra/projector3d_c.pyx @@ -87,12 +87,18 @@ cdef CProjector3D * getObject(i) except NULL:  def projection_geometry(i):      cdef CProjector3D * proj = getObject(i) -    return utils.configToDict(proj.getProjectionGeometry().getConfiguration()) +    cdef Config * cfg = proj.getProjectionGeometry().getConfiguration() +    dct = utils.configToDict(cfg) +    del cfg +    return dct  def volume_geometry(i):      cdef CProjector3D * proj = getObject(i) -    return utils.configToDict(proj.getVolumeGeometry().getConfiguration()) +    cdef Config * cfg = proj.getVolumeGeometry().getConfiguration() +    dct = utils.configToDict(cfg) +    del cfg +    return dct  def weights_single_ray(i, projection_index, detector_index): diff --git a/python/astra/projector_c.pyx b/python/astra/projector_c.pyx index 9aa868e..77c64a4 100644 --- a/python/astra/projector_c.pyx +++ b/python/astra/projector_c.pyx @@ -91,12 +91,18 @@ cdef CProjector2D * getObject(i) except NULL:  def projection_geometry(i):      cdef CProjector2D * proj = getObject(i) -    return utils.configToDict(proj.getProjectionGeometry().getConfiguration()) +    cdef Config * cfg = proj.getProjectionGeometry().getConfiguration() +    dct = utils.configToDict(cfg) +    del cfg +    return dct  def volume_geometry(i):      cdef CProjector2D * proj = getObject(i) -    return utils.configToDict(proj.getVolumeGeometry().getConfiguration()) +    cdef Config * cfg = proj.getVolumeGeometry().getConfiguration() +    dct = utils.configToDict(cfg) +    del cfg +    return dct  def weights_single_ray(i, projection_index, detector_index): diff --git a/python/astra/pythonutils.py b/python/astra/pythonutils.py new file mode 100644 index 0000000..8ea4af5 --- /dev/null +++ b/python/astra/pythonutils.py @@ -0,0 +1,63 @@ +#----------------------------------------------------------------------- +# Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam +# +# Author: Daniel M. Pelt +# Contact: D.M.Pelt@cwi.nl +# Website: http://dmpelt.github.io/pyastratoolbox/ +# +# +# This file is part of the Python interface to the +# All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). +# +# The Python interface to the ASTRA Toolbox is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +# +# The Python interface to the ASTRA Toolbox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the Python interface to the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. +# +#----------------------------------------------------------------------- +"""Additional purely Python functions for PyAstraToolbox. + +.. moduleauthor:: Daniel M. Pelt <D.M.Pelt@cwi.nl> + + +""" + +def geom_size(geom, dim=None): +    """Returns the size of a volume or sinogram, based on the projection or volume geometry. + +    :param geom: Geometry to calculate size from +    :type geometry: :class:`dict` +    :param dim: Optional axis index to return +    :type dim: :class:`int` +    """ + +    if 'GridSliceCount' in geom: +        # 3D Volume geometry? +        s = (geom['GridSliceCount'], geom[ +             'GridRowCount'], geom['GridColCount']) +    elif 'GridColCount' in geom: +        # 2D Volume geometry? +        s = (geom['GridRowCount'], geom['GridColCount']) +    elif geom['type'] == 'parallel' or geom['type'] == 'fanflat': +        s = (len(geom['ProjectionAngles']), geom['DetectorCount']) +    elif geom['type'] == 'parallel3d' or geom['type'] == 'cone': +        s = (geom['DetectorRowCount'], len( +            geom['ProjectionAngles']), geom['DetectorColCount']) +    elif geom['type'] == 'fanflat_vec': +        s = (geom['Vectors'].shape[0], geom['DetectorCount']) +    elif geom['type'] == 'parallel3d_vec' or geom['type'] == 'cone_vec': +        s = (geom['DetectorRowCount'], geom[ +             'Vectors'].shape[0], geom['DetectorColCount']) + +    if dim != None: +        s = s[dim] + +    return s diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx index 0439f1b..260c308 100644 --- a/python/astra/utils.pyx +++ b/python/astra/utils.pyx @@ -26,6 +26,7 @@  # distutils: language = c++  # distutils: libraries = astra +cimport numpy as np  import numpy as np  import six  from libcpp.string cimport string @@ -80,11 +81,12 @@ def wrap_from_bytes(value):      return s -cdef void readDict(XMLNode * root, _dc): -    cdef XMLNode * listbase -    cdef XMLNode * itm +cdef void readDict(XMLNode root, _dc): +    cdef XMLNode listbase +    cdef XMLNode itm      cdef int i      cdef int j +    cdef double* data      dc = convert_item(_dc)      for item in dc: @@ -93,45 +95,32 @@ cdef void readDict(XMLNode * root, _dc):              if val.size == 0:                  break              listbase = root.addChildNode(item) -            listbase.addAttribute(< string > six.b('listsize'), < float32 > val.size) -            index = 0 +            contig_data = np.ascontiguousarray(val,dtype=np.float64) +            data = <double*>np.PyArray_DATA(contig_data)               if val.ndim == 2: -                for i in range(val.shape[0]): -                    for j in range(val.shape[1]): -                        itm = listbase.addChildNode(six.b('ListItem')) -                        itm.addAttribute(< string > six.b('index'), < float32 > index) -                        itm.addAttribute( < string > six.b('value'), < float32 > val[i, j]) -                        index += 1 -                        del itm +                listbase.setContent(data, val.shape[1], val.shape[0], False)              elif val.ndim == 1: -                for i in range(val.shape[0]): -                    itm = listbase.addChildNode(six.b('ListItem')) -                    itm.addAttribute(< string > six.b('index'), < float32 > index) -                    itm.addAttribute(< string > six.b('value'), < float32 > val[i]) -                    index += 1 -                    del itm +                listbase.setContent(data, val.shape[0])              else:                  raise Exception("Only 1 or 2 dimensions are allowed") -            del listbase          elif isinstance(val, dict):              if item == six.b('option') or item == six.b('options') or item == six.b('Option') or item == six.b('Options'):                  readOptions(root, val)              else:                  itm = root.addChildNode(item)                  readDict(itm, val) -                del itm          else:              if item == six.b('type'):                  root.addAttribute(< string > six.b('type'), <string> wrap_to_bytes(val))              else:                  itm = root.addChildNode(item, wrap_to_bytes(val)) -                del itm -cdef void readOptions(XMLNode * node, dc): -    cdef XMLNode * listbase -    cdef XMLNode * itm +cdef void readOptions(XMLNode node, dc): +    cdef XMLNode listbase +    cdef XMLNode itm      cdef int i      cdef int j +    cdef double* data      for item in dc:          val = dc[item]          if node.hasOption(item): @@ -141,26 +130,14 @@ cdef void readOptions(XMLNode * node, dc):                  break              listbase = node.addChildNode(six.b('Option'))              listbase.addAttribute(< string > six.b('key'), < string > item) -            listbase.addAttribute(< string > six.b('listsize'), < float32 > val.size) -            index = 0 +            contig_data = np.ascontiguousarray(val,dtype=np.float64) +            data = <double*>np.PyArray_DATA(contig_data)              if val.ndim == 2: -                for i in range(val.shape[0]): -                    for j in range(val.shape[1]): -                        itm = listbase.addChildNode(six.b('ListItem')) -                        itm.addAttribute(< string > six.b('index'), < float32 > index) -                        itm.addAttribute( < string > six.b('value'), < float32 > val[i, j]) -                        index += 1 -                        del itm +                listbase.setContent(data, val.shape[1], val.shape[0], False)              elif val.ndim == 1: -                for i in range(val.shape[0]): -                    itm = listbase.addChildNode(six.b('ListItem')) -                    itm.addAttribute(< string > six.b('index'), < float32 > index) -                    itm.addAttribute(< string > six.b('value'), < float32 > val[i]) -                    index += 1 -                    del itm +                listbase.setContent(data, val.shape[0])              else:                  raise Exception("Only 1 or 2 dimensions are allowed") -            del listbase          else:              node.addOption(item, wrap_to_bytes(val)) @@ -214,10 +191,10 @@ def stringToPythonValue(inputIn):              return str(input) -cdef XMLNode2dict(XMLNode * node): -    cdef XMLNode * subnode -    cdef list[XMLNode * ] nodes -    cdef list[XMLNode * ].iterator it +cdef XMLNode2dict(XMLNode node): +    cdef XMLNode subnode +    cdef list[XMLNode] nodes +    cdef list[XMLNode].iterator it      dct = {}      opts = {}      if node.hasAttribute(six.b('type')): @@ -227,10 +204,12 @@ cdef XMLNode2dict(XMLNode * node):      while it != nodes.end():          subnode = deref(it)          if castString(subnode.getName())=="Option": -            opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getAttribute('value')) +            if subnode.hasAttribute('value'): +                opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getAttribute('value')) +            else: +                opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getContent())          else:              dct[castString(subnode.getName())] = stringToPythonValue(subnode.getContent()) -        del subnode          inc(it)      if len(opts)>0: dct['options'] = opts      return dct diff --git a/python/docSRC/index.rst b/python/docSRC/index.rst index 8d17a4a..b7cc6d6 100644 --- a/python/docSRC/index.rst +++ b/python/docSRC/index.rst @@ -18,7 +18,7 @@ Contents:     matrix     creators     functions -   ASTRAProjector +   operator     matlab     astra  .. astra diff --git a/python/docSRC/ASTRAProjector.rst b/python/docSRC/operator.rst index 1c267e3..fe500ba 100644 --- a/python/docSRC/ASTRAProjector.rst +++ b/python/docSRC/operator.rst @@ -1,7 +1,7 @@ -Helper class: the :mod:`ASTRAProjector` module +OpTomo class: the :mod:`optomo` module  ============================================== -.. automodule:: astra.ASTRAProjector +.. automodule:: astra.optomo      :members:      :undoc-members:      :show-inheritance: diff --git a/samples/matlab/s010_supersampling.m b/samples/matlab/s010_supersampling.m index 80f6f56..148f6ad 100644 --- a/samples/matlab/s010_supersampling.m +++ b/samples/matlab/s010_supersampling.m @@ -12,23 +12,15 @@ vol_geom = astra_create_vol_geom(256, 256);  proj_geom = astra_create_proj_geom('parallel', 3.0, 128, linspace2(0,pi,180));  P = phantom(256); -% Because the astra_create_sino_gpu wrapper does not have support for -% all possible algorithm options, we manually create a sinogram -phantom_id = astra_mex_data2d('create', '-vol', vol_geom, P); -sinogram_id = astra_mex_data2d('create', '-sino', proj_geom); -cfg = astra_struct('FP_CUDA'); -cfg.VolumeDataId = phantom_id; -cfg.ProjectionDataId = sinogram_id; +% We create a projector set up to use 3 rays per detector element +cfg_proj = astra_struct('cuda'); +cfg_proj.option.DetectorSuperSampling = 3; +cfg_proj.ProjectionGeometry = proj_geom; +cfg_proj.VolumeGeometry = vol_geom; +proj_id = astra_mex_projector('create', cfg_proj); -% Set up 3 rays per detector element -cfg.option.DetectorSuperSampling = 3; -alg_id = astra_mex_algorithm('create', cfg); -astra_mex_algorithm('run', alg_id); -astra_mex_algorithm('delete', alg_id); -astra_mex_data2d('delete', phantom_id); - -sinogram3 = astra_mex_data2d('get', sinogram_id); +[sinogram3 sinogram_id] = astra_create_sino(P, proj_id);  figure(1); imshow(P, []);  figure(2); imshow(sinogram3, []); @@ -39,14 +31,14 @@ rec_id = astra_mex_data2d('create', '-vol', vol_geom);  cfg = astra_struct('SIRT_CUDA');  cfg.ReconstructionDataId = rec_id;  cfg.ProjectionDataId = sinogram_id; -% Set up 3 rays per detector element -cfg.option.DetectorSuperSampling = 3; +cfg.ProjectorId = proj_id; +  % There is also an option for supersampling during the backprojection step.  % This should be used if your detector pixels are smaller than the voxels.  % Set up 2 rays per image pixel dimension, for 4 rays total per image pixel. -% cfg.option.PixelSuperSampling = 2; +% cfg_proj.option.PixelSuperSampling = 2;  alg_id = astra_mex_algorithm('create', cfg); diff --git a/samples/matlab/s017_opTomo.m b/samples/matlab/s017_opTomo.m new file mode 100644 index 0000000..891a93d --- /dev/null +++ b/samples/matlab/s017_opTomo.m @@ -0,0 +1,62 @@ +% ----------------------------------------------------------------------- +% This file is part of the ASTRA Toolbox +%  +% Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp +%            2014-2015, CWI, Amsterdam +% License: Open Source under GPLv3 +% Contact: astra@uantwerpen.be +% Website: http://sf.net/projects/astra-toolbox +% ----------------------------------------------------------------------- + +% This sample illustrates the use of opTomo. +% +% opTomo is a wrapper around the FP and BP operations of the ASTRA Toolbox, +% to allow you to use them as you would a matrix. +% +% This class requires the Spot Linear-Operator Toolbox to be installed. +% You can download this at http://www.cs.ubc.ca/labs/scl/spot/ + +% load a phantom image +im = phantom(256); +% and flatten it to a vector +x = im(:); + +%% Setting up the geometry +% projection geometry +proj_geom = astra_create_proj_geom('parallel', 1, 256, linspace2(0,pi,180)); +% object dimensions +vol_geom  = astra_create_vol_geom(256,256); + +%% Generate projection data +% Create the Spot operator for ASTRA using the GPU. +W = opTomo('cuda', proj_geom, vol_geom); + +p = W*x; + +% reshape the vector into a sinogram +sinogram = reshape(p, W.proj_size); +imshow(sinogram, []); + + +%% Reconstruction +% We use a least squares solver lsqr from Matlab to solve the  +% equation W*x = p. +% Max number of iterations is 100, convergence tolerance of 1e-6. +y = lsqr(W, p, 1e-6, 100); + +% the output is a vector, so we reshape it into an image +reconstruction = reshape(y, W.vol_size); + +subplot(1,3,1); +imshow(reconstruction, []); +title('Reconstruction'); + +subplot(1,3,2); +imshow(im, []); +title('Ground truth'); + +% The transpose of the operator corresponds to the backprojection. +backProjection = W'*p; +subplot(1,3,3); +imshow(reshape(backProjection, W.vol_size), []); +title('Backprojection'); diff --git a/samples/python/s005_3d_geometry.py b/samples/python/s005_3d_geometry.py index f43fc7e..a7f7a3d 100644 --- a/samples/python/s005_3d_geometry.py +++ b/samples/python/s005_3d_geometry.py @@ -24,7 +24,11 @@  #  #----------------------------------------------------------------------- -from six.moves import range +try: +    from six.moves import range +except ImportError: +    # six 1.3.0 +    from six.moves import xrange as range  import astra  import numpy as np diff --git a/samples/python/s016_plots.py b/samples/python/s016_plots.py index cd4d98c..8a8ba64 100644 --- a/samples/python/s016_plots.py +++ b/samples/python/s016_plots.py @@ -24,7 +24,11 @@  #  #----------------------------------------------------------------------- -from six.moves import range +try: +    from six.moves import range +except ImportError: +    # six 1.3.0 +    from six.moves import xrange as range  import astra  import numpy as np @@ -35,8 +39,8 @@ proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180  # As before, create a sinogram from a phantom  import scipy.io  P = scipy.io.loadmat('phantom.mat')['phantom256'] -proj_id = astra.create_projector('line',proj_geom,vol_geom) -sinogram_id, sinogram = astra.create_sino(P, proj_id,useCUDA=True) +proj_id = astra.create_projector('cuda',proj_geom,vol_geom) +sinogram_id, sinogram = astra.create_sino(P, proj_id)  import pylab  pylab.gray() diff --git a/samples/python/s017_OpTomo.py b/samples/python/s017_OpTomo.py new file mode 100644 index 0000000..967fa64 --- /dev/null +++ b/samples/python/s017_OpTomo.py @@ -0,0 +1,61 @@ +#----------------------------------------------------------------------- +#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam +# +#Author: Daniel M. Pelt +#Contact: D.M.Pelt@cwi.nl +#Website: http://dmpelt.github.io/pyastratoolbox/ +# +# +#This file is part of the Python interface to the +#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). +# +#The Python interface to the ASTRA Toolbox is free software: you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation, either version 3 of the License, or +#(at your option) any later version. +# +#The Python interface to the ASTRA Toolbox is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. +# +#You should have received a copy of the GNU General Public License +#along with the Python interface to the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. +# +#----------------------------------------------------------------------- + +import astra +import numpy as np +import scipy.sparse.linalg + +vol_geom = astra.create_vol_geom(256, 256) +proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False)) + +# As before, create a sinogram from a phantom +import scipy.io +P = scipy.io.loadmat('phantom.mat')['phantom256'] +proj_id = astra.create_projector('cuda',proj_geom,vol_geom) + +# construct the OpTomo object +W = astra.OpTomo(proj_id) + +sinogram = W * P +sinogram = sinogram.reshape([180, 384]) + +import pylab +pylab.gray() +pylab.figure(1) +pylab.imshow(P) +pylab.figure(2) +pylab.imshow(sinogram) + +# Run the lsqr linear solver +output = scipy.sparse.linalg.lsqr(W, sinogram.flatten(), iter_lim=150) +rec = output[0].reshape([256, 256]) + +pylab.figure(3) +pylab.imshow(rec) +pylab.show() + +# Clean up. +astra.projector.delete(proj_id) diff --git a/src/ArtAlgorithm.cpp b/src/ArtAlgorithm.cpp index 8f058a3..6a699ec 100644 --- a/src/ArtAlgorithm.cpp +++ b/src/ArtAlgorithm.cpp @@ -132,7 +132,7 @@ bool CArtAlgorithm::initialize(const Config& _cfg)  	}  	// ray order -	string projOrder = _cfg.self->getOption("RayOrder", "sequential"); +	string projOrder = _cfg.self.getOption("RayOrder", "sequential");  	CC.markOptionParsed("RayOrder");  	m_iCurrentRay = 0;  	m_iRayCount = m_pProjector->getProjectionGeometry()->getProjectionAngleCount() *  @@ -145,7 +145,7 @@ bool CArtAlgorithm::initialize(const Config& _cfg)  			m_piDetectorOrder[i] = i % m_pProjector->getProjectionGeometry()->getDetectorCount();  		}  	} else if (projOrder == "custom") { -		vector<float32> rayOrderList = _cfg.self->getOptionNumericalArray("RayOrderList"); +		vector<float32> rayOrderList = _cfg.self.getOptionNumericalArray("RayOrderList");  		m_iRayCount = rayOrderList.size() / 2;  		m_piProjectionOrder = new int[m_iRayCount];  		m_piDetectorOrder = new int[m_iRayCount]; @@ -158,7 +158,7 @@ bool CArtAlgorithm::initialize(const Config& _cfg)  		return false;  	} -	m_fLambda = _cfg.self->getOptionNumerical("Lambda", 1.0f); +	m_fLambda = _cfg.self.getOptionNumerical("Lambda", 1.0f);  	CC.markOptionParsed("Lambda");  	// success diff --git a/src/ConeProjectionGeometry3D.cpp b/src/ConeProjectionGeometry3D.cpp index 1976901..dd22eba 100644 --- a/src/ConeProjectionGeometry3D.cpp +++ b/src/ConeProjectionGeometry3D.cpp @@ -87,17 +87,15 @@ bool CConeProjectionGeometry3D::initialize(const Config& _cfg)  	CProjectionGeometry3D::initialize(_cfg);  	// Required: DistanceOriginDetector -	XMLNode* node = _cfg.self->getSingleNode("DistanceOriginDetector"); +	XMLNode node = _cfg.self.getSingleNode("DistanceOriginDetector");  	ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginDetector tag specified."); -	m_fOriginDetectorDistance = boost::lexical_cast<float32>(node->getContent()); -	ASTRA_DELETE(node); +	m_fOriginDetectorDistance = boost::lexical_cast<float32>(node.getContent());  	CC.markNodeParsed("DistanceOriginDetector");  	// Required: DetectorOriginSource -	node = _cfg.self->getSingleNode("DistanceOriginSource"); +	node = _cfg.self.getSingleNode("DistanceOriginSource");  	ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginSource tag specified."); -	m_fOriginSourceDistance = boost::lexical_cast<float32>(node->getContent()); -	ASTRA_DELETE(node); +	m_fOriginSourceDistance = boost::lexical_cast<float32>(node.getContent());  	CC.markNodeParsed("DistanceOriginSource");  	// success @@ -193,14 +191,14 @@ Config* CConeProjectionGeometry3D::getConfiguration() const  {  	Config* cfg = new Config();  	cfg->initialize("ProjectionGeometry3D"); -	cfg->self->addAttribute("type", "cone"); -	cfg->self->addChildNode("DetectorSpacingX", m_fDetectorSpacingX); -	cfg->self->addChildNode("DetectorSpacingY", m_fDetectorSpacingY); -	cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); -	cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); -	cfg->self->addChildNode("DistanceOriginDetector", m_fOriginDetectorDistance); -	cfg->self->addChildNode("DistanceOriginSource", m_fOriginSourceDistance); -	cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); +	cfg->self.addAttribute("type", "cone"); +	cfg->self.addChildNode("DetectorSpacingX", m_fDetectorSpacingX); +	cfg->self.addChildNode("DetectorSpacingY", m_fDetectorSpacingY); +	cfg->self.addChildNode("DetectorRowCount", m_iDetectorRowCount); +	cfg->self.addChildNode("DetectorColCount", m_iDetectorColCount); +	cfg->self.addChildNode("DistanceOriginDetector", m_fOriginDetectorDistance); +	cfg->self.addChildNode("DistanceOriginSource", m_fOriginSourceDistance); +	cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);  	return cfg;  } diff --git a/src/ConeVecProjectionGeometry3D.cpp b/src/ConeVecProjectionGeometry3D.cpp index 9dc273d..47ed630 100644 --- a/src/ConeVecProjectionGeometry3D.cpp +++ b/src/ConeVecProjectionGeometry3D.cpp @@ -73,33 +73,30 @@ bool CConeVecProjectionGeometry3D::initialize(const Config& _cfg)  	ASTRA_ASSERT(_cfg.self);  	ConfigStackCheck<CProjectionGeometry3D> CC("ConeVecProjectionGeometry3D", this, _cfg);	 -	XMLNode* node; +	XMLNode node;  	// TODO: Fix up class hierarchy... this class doesn't fit very well.  	// initialization of parent class  	//CProjectionGeometry3D::initialize(_cfg);  	// Required: DetectorRowCount -	node = _cfg.self->getSingleNode("DetectorRowCount"); +	node = _cfg.self.getSingleNode("DetectorRowCount");  	ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorRowCount tag specified."); -	m_iDetectorRowCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iDetectorRowCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("DetectorRowCount");  	// Required: DetectorColCount -	node = _cfg.self->getSingleNode("DetectorColCount"); +	node = _cfg.self.getSingleNode("DetectorColCount");  	ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorColCount tag specified."); -	m_iDetectorColCount = boost::lexical_cast<int>(node->getContent()); +	m_iDetectorColCount = boost::lexical_cast<int>(node.getContent());  	m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; -	ASTRA_DELETE(node);  	CC.markNodeParsed("DetectorColCount");  	// Required: Vectors -	node = _cfg.self->getSingleNode("Vectors"); +	node = _cfg.self.getSingleNode("Vectors");  	ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No Vectors tag specified."); -	vector<double> data = node->getContentNumericalArrayDouble(); +	vector<double> data = node.getContentNumericalArrayDouble();  	CC.markNodeParsed("Vectors"); -	ASTRA_DELETE(node);  	ASTRA_CONFIG_CHECK(data.size() % 12 == 0, "ConeVecProjectionGeometry3D", "Vectors doesn't consist of 12-tuples.");  	m_iProjectionAngleCount = data.size() / 12;  	m_pProjectionAngles = new SConeProjection[m_iProjectionAngleCount]; @@ -208,9 +205,9 @@ Config* CConeVecProjectionGeometry3D::getConfiguration() const  	Config* cfg = new Config();  	cfg->initialize("ProjectionGeometry3D"); -	cfg->self->addAttribute("type", "cone_vec"); -	cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); -	cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); +	cfg->self.addAttribute("type", "cone_vec"); +	cfg->self.addChildNode("DetectorRowCount", m_iDetectorRowCount); +	cfg->self.addChildNode("DetectorColCount", m_iDetectorColCount);  	std::string vectors = "";  	for (int i = 0; i < m_iProjectionAngleCount; ++i) { @@ -229,7 +226,7 @@ Config* CConeVecProjectionGeometry3D::getConfiguration() const  		vectors += boost::lexical_cast<string>(p.fDetVZ);  		if (i < m_iProjectionAngleCount-1) vectors += ';';  	} -	cfg->self->addChildNode("Vectors", vectors); +	cfg->self.addChildNode("Vectors", vectors);  	return cfg;  } diff --git a/src/Config.cpp b/src/Config.cpp index d860638..395080b 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -45,31 +45,33 @@ using namespace std;  //-----------------------------------------------------------------------------  // default constructor -Config::Config() +Config::Config() : self()  { -	self = 0; +	_doc = 0;  }  //-----------------------------------------------------------------------------  // not so default constructor -Config::Config(XMLNode* _self)  +Config::Config(XMLNode _self)  {  	self = _self; +	_doc = 0;  }  //-----------------------------------------------------------------------------  Config::~Config()  { -	delete self; -	self = 0; +	delete _doc; +	_doc = 0;  }  //-----------------------------------------------------------------------------  void Config::initialize(std::string rootname)  { -	if (self == 0) { +	if (!self) {  		XMLDocument* doc = XMLDocument::createDocument(rootname);  		self = doc->getRootNode();		 +		_doc = doc;  	}  } @@ -124,13 +126,13 @@ bool ConfigStackCheck<T>::stopParsing()  	std::string errors; -	std::list<XMLNode*> nodes = cfg->self->getNodes(); -	for (std::list<XMLNode*>::iterator i = nodes.begin(); i != nodes.end(); ++i) +	std::list<XMLNode> nodes = cfg->self.getNodes(); +	for (std::list<XMLNode>::iterator i = nodes.begin(); i != nodes.end(); ++i)  	{ -		std::string nodeName = (*i)->getName(); +		std::string nodeName = i->getName();  		if (nodeName == "Option") { -			nodeName = (*i)->getAttribute("key", ""); +			nodeName = i->getAttribute("key", "");  			if (object->configCheckData->parsedOptions.find(nodeName) == object->configCheckData->parsedOptions.end()) {  				if (!errors.empty()) errors += ", ";  				errors += nodeName; @@ -142,8 +144,6 @@ bool ConfigStackCheck<T>::stopParsing()  			}  		}  	} -	for (std::list<XMLNode*>::iterator i = nodes.begin(); i != nodes.end(); ++i) -		delete (*i);  	nodes.clear();  	if (!errors.empty()) { diff --git a/src/CudaBackProjectionAlgorithm3D.cpp b/src/CudaBackProjectionAlgorithm3D.cpp index a8a1b0a..a5c3445 100644 --- a/src/CudaBackProjectionAlgorithm3D.cpp +++ b/src/CudaBackProjectionAlgorithm3D.cpp @@ -32,6 +32,7 @@ $Id$  #include "astra/AstraObjectManager.h" +#include "astra/CudaProjector3D.h"  #include "astra/ConeProjectionGeometry3D.h"  #include "astra/ParallelProjectionGeometry3D.h"  #include "astra/ParallelVecProjectionGeometry3D.h" @@ -102,12 +103,23 @@ bool CCudaBackProjectionAlgorithm3D::initialize(const Config& _cfg)  		return false;  	} -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); +	CCudaProjector3D* pCudaProjector = 0; +	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector); +	if (!pCudaProjector) { +		// TODO: Report +	} + +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);  	CC.markOptionParsed("GPUindex"); -	m_iVoxelSuperSampling = (int)_cfg.self->getOptionNumerical("VoxelSuperSampling", 1); + + +	m_iVoxelSuperSampling = 1; +	if (pCudaProjector) +		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling(); +	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);  	CC.markOptionParsed("VoxelSuperSampling"); -	m_bSIRTWeighting = _cfg.self->getOptionBool("SIRTWeighting", false); +	m_bSIRTWeighting = _cfg.self.getOptionBool("SIRTWeighting", false);  	CC.markOptionParsed("SIRTWeighting");  	// success diff --git a/src/CudaCglsAlgorithm3D.cpp b/src/CudaCglsAlgorithm3D.cpp index 3677458..2d28964 100644 --- a/src/CudaCglsAlgorithm3D.cpp +++ b/src/CudaCglsAlgorithm3D.cpp @@ -32,6 +32,7 @@ $Id$  #include "astra/AstraObjectManager.h" +#include "astra/CudaProjector3D.h"  #include "astra/ConeProjectionGeometry3D.h"  #include "astra/ParallelVecProjectionGeometry3D.h"  #include "astra/ConeVecProjectionGeometry3D.h" @@ -106,12 +107,27 @@ bool CCudaCglsAlgorithm3D::initialize(const Config& _cfg)  		return false;  	} -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); +	CCudaProjector3D* pCudaProjector = 0; +	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector); +	if (!pCudaProjector) { +		// TODO: Report +	} + +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);  	CC.markOptionParsed("GPUindex"); -	m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); -	CC.markOptionParsed("DetectorSuperSampling"); -	m_iVoxelSuperSampling = (int)_cfg.self->getOptionNumerical("VoxelSuperSampling", 1); + +	m_iVoxelSuperSampling = 1; +	m_iDetectorSuperSampling = 1; +	if (pCudaProjector) { +		// New interface +		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling(); +		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling(); +	} +	// Deprecated options +	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling); +	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);  	CC.markOptionParsed("VoxelSuperSampling"); +	CC.markOptionParsed("DetectorSuperSampling");  	m_pCgls = new AstraCGLS3d(); diff --git a/src/CudaDartMaskAlgorithm.cpp b/src/CudaDartMaskAlgorithm.cpp index dcdefcc..950b428 100644 --- a/src/CudaDartMaskAlgorithm.cpp +++ b/src/CudaDartMaskAlgorithm.cpp @@ -65,38 +65,36 @@ bool CCudaDartMaskAlgorithm::initialize(const Config& _cfg)  	ConfigStackCheck<CAlgorithm> CC("CudaDartMaskAlgorithm", this, _cfg);  	// reconstruction data -	XMLNode* node = _cfg.self->getSingleNode("SegmentationDataId"); +	XMLNode node = _cfg.self.getSingleNode("SegmentationDataId");  	ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No SegmentationDataId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pSegmentation = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("SegmentationDataId");  	// reconstruction data -	node = _cfg.self->getSingleNode("MaskDataId"); +	node = _cfg.self.getSingleNode("MaskDataId");  	ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No MaskDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pMask = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("MaskDataId");  	// Option: GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);  	CC.markOptionParsed("GPUindex"); -	if (!_cfg.self->hasOption("GPUindex")) +	if (!_cfg.self.hasOption("GPUindex"))  		CC.markOptionParsed("GPUIndex");      // Option: Connectivity -	m_iConn = (unsigned int)_cfg.self->getOptionNumerical("Connectivity", 8); +	m_iConn = (unsigned int)_cfg.self.getOptionNumerical("Connectivity", 8);  	CC.markOptionParsed("Connectivity");  	// Option: Threshold -	m_iThreshold = (unsigned int)_cfg.self->getOptionNumerical("Threshold", 1); +	m_iThreshold = (unsigned int)_cfg.self.getOptionNumerical("Threshold", 1);  	CC.markOptionParsed("Threshold");  	// Option: Radius -	m_iRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 1); +	m_iRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 1);  	CC.markOptionParsed("Radius");  	_check(); diff --git a/src/CudaDartMaskAlgorithm3D.cpp b/src/CudaDartMaskAlgorithm3D.cpp index f3500b9..b0dfc5b 100644 --- a/src/CudaDartMaskAlgorithm3D.cpp +++ b/src/CudaDartMaskAlgorithm3D.cpp @@ -65,38 +65,36 @@ bool CCudaDartMaskAlgorithm3D::initialize(const Config& _cfg)  	ConfigStackCheck<CAlgorithm> CC("CudaDartMaskAlgorithm", this, _cfg);  	// reconstruction data -	XMLNode* node = _cfg.self->getSingleNode("SegmentationDataId"); +	XMLNode node = _cfg.self.getSingleNode("SegmentationDataId");  	ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No SegmentationDataId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pSegmentation = dynamic_cast<CFloat32VolumeData3DMemory*>(CData3DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("SegmentationDataId");  	// reconstruction data -	node = _cfg.self->getSingleNode("MaskDataId"); +	node = _cfg.self.getSingleNode("MaskDataId");  	ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No MaskDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pMask = dynamic_cast<CFloat32VolumeData3DMemory*>(CData3DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("MaskDataId");  	// Option: GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);  	CC.markOptionParsed("GPUindex"); -	if (!_cfg.self->hasOption("GPUindex")) +	if (!_cfg.self.hasOption("GPUindex"))  		CC.markOptionParsed("GPUIndex");      // Option: Connectivity -	m_iConn = (unsigned int)_cfg.self->getOptionNumerical("Connectivity", 8); +	m_iConn = (unsigned int)_cfg.self.getOptionNumerical("Connectivity", 8);  	CC.markOptionParsed("Connectivity");  	// Option: Threshold -	m_iThreshold = (unsigned int)_cfg.self->getOptionNumerical("Threshold", 1); +	m_iThreshold = (unsigned int)_cfg.self.getOptionNumerical("Threshold", 1);  	CC.markOptionParsed("Threshold");  	// Option: Radius -	m_iRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 1); +	m_iRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 1);  	CC.markOptionParsed("Radius");  	_check(); diff --git a/src/CudaDartSmoothingAlgorithm.cpp b/src/CudaDartSmoothingAlgorithm.cpp index 2f2103f..7e22809 100644 --- a/src/CudaDartSmoothingAlgorithm.cpp +++ b/src/CudaDartSmoothingAlgorithm.cpp @@ -65,34 +65,32 @@ bool CCudaDartSmoothingAlgorithm::initialize(const Config& _cfg)  	ConfigStackCheck<CAlgorithm> CC("CudaDartSmoothingAlgorithm", this, _cfg);  	// reconstruction data -	XMLNode* node = _cfg.self->getSingleNode("InDataId"); +	XMLNode node = _cfg.self.getSingleNode("InDataId");  	ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No InDataId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pIn = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("InDataId");  	// reconstruction data -	node = _cfg.self->getSingleNode("OutDataId"); +	node = _cfg.self.getSingleNode("OutDataId");  	ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No OutDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pOut = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("OutDataId");  	// Option: GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);  	CC.markOptionParsed("GPUindex"); -	if (!_cfg.self->hasOption("GPUindex")) +	if (!_cfg.self.hasOption("GPUindex"))  		CC.markOptionParsed("GPUIndex");  	// Option: Radius -	m_fB = (float)_cfg.self->getOptionNumerical("Intensity", 0.3f); +	m_fB = (float)_cfg.self.getOptionNumerical("Intensity", 0.3f);  	CC.markOptionParsed("Intensity");  	// Option: Radius -	m_iRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 1); +	m_iRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 1);  	CC.markOptionParsed("Radius"); diff --git a/src/CudaDartSmoothingAlgorithm3D.cpp b/src/CudaDartSmoothingAlgorithm3D.cpp index f3cf015..9c4437a 100644 --- a/src/CudaDartSmoothingAlgorithm3D.cpp +++ b/src/CudaDartSmoothingAlgorithm3D.cpp @@ -65,34 +65,32 @@ bool CCudaDartSmoothingAlgorithm3D::initialize(const Config& _cfg)  	ConfigStackCheck<CAlgorithm> CC("CudaDartSmoothingAlgorithm", this, _cfg);  	// reconstruction data -	XMLNode* node = _cfg.self->getSingleNode("InDataId"); +	XMLNode node = _cfg.self.getSingleNode("InDataId");  	ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No InDataId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pIn = dynamic_cast<CFloat32VolumeData3DMemory*>(CData3DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("InDataId");  	// reconstruction data -	node = _cfg.self->getSingleNode("OutDataId"); +	node = _cfg.self.getSingleNode("OutDataId");  	ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No OutDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pOut = dynamic_cast<CFloat32VolumeData3DMemory*>(CData3DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("OutDataId");  	// Option: GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);  	CC.markOptionParsed("GPUindex"); -	if (!_cfg.self->hasOption("GPUindex")) +	if (!_cfg.self.hasOption("GPUindex"))  		CC.markOptionParsed("GPUIndex");  	// Option: Intensity -	m_fB = (float)_cfg.self->getOptionNumerical("Intensity", 0.3f); +	m_fB = (float)_cfg.self.getOptionNumerical("Intensity", 0.3f);  	CC.markOptionParsed("Intensity");  	// Option: Radius -	m_iRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 1); +	m_iRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 1);  	CC.markOptionParsed("Radius");  	_check(); diff --git a/src/CudaDataOperationAlgorithm.cpp b/src/CudaDataOperationAlgorithm.cpp index 79a9d7f..ae133c2 100644 --- a/src/CudaDataOperationAlgorithm.cpp +++ b/src/CudaDataOperationAlgorithm.cpp @@ -67,40 +67,37 @@ bool CCudaDataOperationAlgorithm::initialize(const Config& _cfg)  	ConfigStackCheck<CAlgorithm> CC("CCudaDataOperationAlgorithm", this, _cfg);  	// operation -	XMLNode* node = _cfg.self->getSingleNode("Operation"); +	XMLNode node = _cfg.self.getSingleNode("Operation");  	ASTRA_CONFIG_CHECK(node, "CCudaDataOperationAlgorithm", "No Operation tag specified."); -	m_sOperation = node->getContent(); +	m_sOperation = node.getContent();  	m_sOperation.erase(std::remove(m_sOperation.begin(), m_sOperation.end(), ' '), m_sOperation.end()); -	ASTRA_DELETE(node);  	CC.markNodeParsed("Operation");  	// data -	node = _cfg.self->getSingleNode("DataId"); +	node = _cfg.self.getSingleNode("DataId");  	ASTRA_CONFIG_CHECK(node, "CCudaDataOperationAlgorithm", "No DataId tag specified."); -	vector<string> data = node->getContentArray(); +	vector<string> data = node.getContentArray();  	for (vector<string>::iterator it = data.begin(); it != data.end(); it++){  		int id = boost::lexical_cast<int>(*it);  		m_pData.push_back(dynamic_cast<CFloat32Data2D*>(CData2DManager::getSingleton().get(id)));  	} -	ASTRA_DELETE(node);  	CC.markNodeParsed("DataId");  	// scalar -	node = _cfg.self->getSingleNode("Scalar"); +	node = _cfg.self.getSingleNode("Scalar");  	ASTRA_CONFIG_CHECK(node, "CCudaDataOperationAlgorithm", "No Scalar tag specified."); -	m_fScalar = node->getContentNumericalArray(); -	ASTRA_DELETE(node); +	m_fScalar = node.getContentNumericalArray();  	CC.markNodeParsed("Scalar");  	// Option: GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);  	CC.markOptionParsed("GPUindex"); -	if (!_cfg.self->hasOption("GPUindex")) +	if (!_cfg.self.hasOption("GPUindex"))  		CC.markOptionParsed("GPUIndex"); -	if (_cfg.self->hasOption("MaskId")) { -		int id = boost::lexical_cast<int>(_cfg.self->getOption("MaskId")); +	if (_cfg.self.hasOption("MaskId")) { +		int id = boost::lexical_cast<int>(_cfg.self.getOption("MaskId"));  		m_pMask = dynamic_cast<CFloat32Data2D*>(CData2DManager::getSingleton().get(id));  	}  	CC.markOptionParsed("MaskId"); diff --git a/src/CudaFDKAlgorithm3D.cpp b/src/CudaFDKAlgorithm3D.cpp index 0a46ff6..e700945 100644 --- a/src/CudaFDKAlgorithm3D.cpp +++ b/src/CudaFDKAlgorithm3D.cpp @@ -32,6 +32,7 @@ $Id$  #include "astra/AstraObjectManager.h" +#include "astra/CudaProjector3D.h"  #include "astra/ConeProjectionGeometry3D.h"  #include "../cuda/3d/astra3d.h" @@ -100,12 +101,22 @@ bool CCudaFDKAlgorithm3D::initialize(const Config& _cfg)  		return false;  	} -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); +	CCudaProjector3D* pCudaProjector = 0; +	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector); +	if (!pCudaProjector) { +		// TODO: Report +	} + +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);  	CC.markOptionParsed("GPUindex"); -	m_iVoxelSuperSampling = (int)_cfg.self->getOptionNumerical("VoxelSuperSampling", 1); + +	m_iVoxelSuperSampling = 1; +	if (pCudaProjector) +		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling(); +	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);  	CC.markOptionParsed("VoxelSuperSampling"); -	m_bShortScan = _cfg.self->getOptionBool("ShortScan", false); +	m_bShortScan = _cfg.self.getOptionBool("ShortScan", false);  	CC.markOptionParsed("ShortScan");  	// success diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp index 0badc20..aac96d6 100644 --- a/src/CudaFilteredBackProjectionAlgorithm.cpp +++ b/src/CudaFilteredBackProjectionAlgorithm.cpp @@ -32,6 +32,7 @@ $Id$  #include <cstring>  #include "astra/AstraObjectManager.h" +#include "astra/CudaProjector2D.h"  #include "../cuda/2d/astra.h"  #include "astra/Logging.h" @@ -77,40 +78,51 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)  		clear();  	} +	// Projector +	XMLNode node = _cfg.self.getSingleNode("ProjectorId"); +	CCudaProjector2D* pCudaProjector = 0; +	if (node) { +		int id = boost::lexical_cast<int>(node.getContent()); +		CProjector2D *projector = CProjector2DManager::getSingleton().get(id); +		pCudaProjector = dynamic_cast<CCudaProjector2D*>(projector); +		if (!pCudaProjector) { +			ASTRA_WARN("non-CUDA Projector2D passed"); +		} +	} +	CC.markNodeParsed("ProjectorId"); + +  	// sinogram data -	XMLNode* node = _cfg.self->getSingleNode("ProjectionDataId"); +	node = _cfg.self.getSingleNode("ProjectionDataId");  	ASTRA_CONFIG_CHECK(node, "CudaFBP", "No ProjectionDataId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ProjectionDataId");  	// reconstruction data -	node = _cfg.self->getSingleNode("ReconstructionDataId"); +	node = _cfg.self.getSingleNode("ReconstructionDataId");  	ASTRA_CONFIG_CHECK(node, "CudaFBP", "No ReconstructionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pReconstruction = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ReconstructionDataId");  	// filter type -	node = _cfg.self->getSingleNode("FilterType"); -	if(node != NULL) +	node = _cfg.self.getSingleNode("FilterType"); +	if (node)  	{ -		m_eFilter = _convertStringToFilter(node->getContent().c_str()); +		m_eFilter = _convertStringToFilter(node.getContent().c_str());  	}  	else  	{  		m_eFilter = FILTER_RAMLAK;  	}  	CC.markNodeParsed("FilterType"); -	ASTRA_DELETE(node);  	// filter -	node = _cfg.self->getSingleNode("FilterSinogramId"); -	if(node != NULL) +	node = _cfg.self.getSingleNode("FilterSinogramId"); +	if (node)  	{ -		id = boost::lexical_cast<int>(node->getContent()); +		id = boost::lexical_cast<int>(node.getContent());  		const CFloat32ProjectionData2D * pFilterData = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));  		m_iFilterWidth = pFilterData->getGeometry()->getDetectorCount();  		int iFilterProjectionCount = pFilterData->getGeometry()->getProjectionAngleCount(); @@ -124,13 +136,12 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)  		m_pfFilter = NULL;  	}  	CC.markNodeParsed("FilterSinogramId"); // TODO: Only for some types! -	ASTRA_DELETE(node);  	// filter parameter -	node = _cfg.self->getSingleNode("FilterParameter"); -	if(node != NULL) +	node = _cfg.self.getSingleNode("FilterParameter"); +	if (node)  	{ -		float fParameter = boost::lexical_cast<float>(node->getContent()); +		float fParameter = boost::lexical_cast<float>(node.getContent());  		m_fFilterParameter = fParameter;  	}  	else @@ -138,13 +149,12 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)  		m_fFilterParameter = -1.0f;  	}  	CC.markNodeParsed("FilterParameter"); // TODO: Only for some types! -	ASTRA_DELETE(node);  	// D value -	node = _cfg.self->getSingleNode("FilterD"); -	if(node != NULL) +	node = _cfg.self.getSingleNode("FilterD"); +	if (node)  	{ -		float fD = boost::lexical_cast<float>(node->getContent()); +		float fD = boost::lexical_cast<float>(node.getContent());  		m_fFilterD = fD;  	}  	else @@ -152,19 +162,24 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)  		m_fFilterD = 1.0f;  	}  	CC.markNodeParsed("FilterD"); // TODO: Only for some types! -	ASTRA_DELETE(node);  	// GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);  	CC.markOptionParsed("GPUindex"); -	// Pixel supersampling factor -	m_iPixelSuperSampling = (int)_cfg.self->getOptionNumerical("PixelSuperSampling", 1); +	m_iPixelSuperSampling = 1; +	if (pCudaProjector) { +		// New interface +		m_iPixelSuperSampling = pCudaProjector->getVoxelSuperSampling(); +	} +	// Deprecated options +	m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", m_iPixelSuperSampling);  	CC.markOptionParsed("PixelSuperSampling"); +  	// Fan beam short scan mode  	if (m_pSinogram && dynamic_cast<CFanFlatProjectionGeometry2D*>(m_pSinogram->getGeometry())) { -		m_bShortScan = (int)_cfg.self->getOptionBool("ShortScan", false); +		m_bShortScan = (int)_cfg.self.getOptionBool("ShortScan", false);  		CC.markOptionParsed("ShortScan");  	} diff --git a/src/CudaForwardProjectionAlgorithm.cpp b/src/CudaForwardProjectionAlgorithm.cpp index 95abb62..b382f2e 100644 --- a/src/CudaForwardProjectionAlgorithm.cpp +++ b/src/CudaForwardProjectionAlgorithm.cpp @@ -71,47 +71,52 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg)  {  	ASTRA_ASSERT(_cfg.self);  	ConfigStackCheck<CAlgorithm> CC("CudaForwardProjectionAlgorithm", this, _cfg); + +	// Projector +	XMLNode node = _cfg.self.getSingleNode("ProjectorId"); +	CCudaProjector2D* pCudaProjector = 0; +	if (node) { +		int id = boost::lexical_cast<int>(node.getContent()); +		CProjector2D *projector = CProjector2DManager::getSingleton().get(id); +		pCudaProjector = dynamic_cast<CCudaProjector2D*>(projector); +		if (!pCudaProjector) { +			ASTRA_WARN("non-CUDA Projector2D passed to FP_CUDA"); +		} +	} +	CC.markNodeParsed("ProjectorId"); + +  	// sinogram data -	XMLNode* node = _cfg.self->getSingleNode("ProjectionDataId"); +	node = _cfg.self.getSingleNode("ProjectionDataId");  	ASTRA_CONFIG_CHECK(node, "FP_CUDA", "No ProjectionDataId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ProjectionDataId");  	// volume data -	node = _cfg.self->getSingleNode("VolumeDataId"); +	node = _cfg.self.getSingleNode("VolumeDataId");  	ASTRA_CONFIG_CHECK(node, "FP_CUDA", "No VolumeDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pVolume = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("VolumeDataId");  	// GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);  	CC.markOptionParsed("GPUindex"); -	if (!_cfg.self->hasOption("GPUindex")) +	if (!_cfg.self.hasOption("GPUindex"))  		CC.markOptionParsed("GPUIndex");  	// Detector supersampling factor -	m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); -	CC.markOptionParsed("DetectorSuperSampling"); - - -	// This isn't used yet, but passing it is not something to warn about -	node = _cfg.self->getSingleNode("ProjectorId"); -	if (node) { -		id = boost::lexical_cast<int>(node->getContent()); -		CProjector2D *projector = CProjector2DManager::getSingleton().get(id); -		if (!dynamic_cast<CCudaProjector2D*>(projector)) { -			ASTRA_WARN("non-CUDA Projector2D passed to FP_CUDA"); -		} -		delete node; +	m_iDetectorSuperSampling = 1; +	if (pCudaProjector) { +		// New interface +		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();  	} -	CC.markNodeParsed("ProjectorId"); -	 +	// Deprecated option +	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling); +	CC.markOptionParsed("DetectorSuperSampling");  	// return success diff --git a/src/CudaForwardProjectionAlgorithm3D.cpp b/src/CudaForwardProjectionAlgorithm3D.cpp index aa36715..3da61ff 100644 --- a/src/CudaForwardProjectionAlgorithm3D.cpp +++ b/src/CudaForwardProjectionAlgorithm3D.cpp @@ -78,40 +78,47 @@ bool CCudaForwardProjectionAlgorithm3D::initialize(const Config& _cfg)  	ASTRA_ASSERT(_cfg.self);  	ConfigStackCheck<CAlgorithm> CC("CudaForwardProjectionAlgorithm3D", this, _cfg);	 -	XMLNode* node; +	XMLNode node;  	int id;  	// sinogram data -	node = _cfg.self->getSingleNode("ProjectionDataId"); +	node = _cfg.self.getSingleNode("ProjectionDataId");  	ASTRA_CONFIG_CHECK(node, "CudaForwardProjection3D", "No ProjectionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pProjections = dynamic_cast<CFloat32ProjectionData3DMemory*>(CData3DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ProjectionDataId");  	// reconstruction data -	node = _cfg.self->getSingleNode("VolumeDataId"); +	node = _cfg.self.getSingleNode("VolumeDataId");  	ASTRA_CONFIG_CHECK(node, "CudaForwardProjection3D", "No VolumeDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pVolume = dynamic_cast<CFloat32VolumeData3DMemory*>(CData3DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("VolumeDataId");  	// optional: projector -	node = _cfg.self->getSingleNode("ProjectorId"); +	node = _cfg.self.getSingleNode("ProjectorId"); +	CCudaProjector3D* pCudaProjector = 0; +	m_pProjector = 0;  	if (node) { -		id = boost::lexical_cast<int>(node->getContent()); +		id = boost::lexical_cast<int>(node.getContent());  		m_pProjector = CProjector3DManager::getSingleton().get(id); -		ASTRA_DELETE(node); -	} else { -		m_pProjector = 0; // TODO: or manually construct default projector? +		pCudaProjector = dynamic_cast<CCudaProjector3D*>(CProjector3DManager::getSingleton().get(id)); +		m_pProjector = pCudaProjector; +		if (!pCudaProjector) { +			// TODO: Report +		}  	}  	CC.markNodeParsed("ProjectorId");  	// GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);  	CC.markOptionParsed("GPUindex"); -	m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); + + +	m_iDetectorSuperSampling = 1; +	if (pCudaProjector) +		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling(); +	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);  	CC.markOptionParsed("DetectorSuperSampling");  	// success diff --git a/src/CudaProjector2D.cpp b/src/CudaProjector2D.cpp index 056ea3b..a26e32d 100644 --- a/src/CudaProjector2D.cpp +++ b/src/CudaProjector2D.cpp @@ -59,6 +59,8 @@ void CCudaProjector2D::_clear()  	m_bIsInitialized = false;  	m_projectionKernel = ker2d_default; +	m_iVoxelSuperSampling = 1; +	m_iDetectorSuperSampling = 1;  }  //---------------------------------------------------------------------------------------- @@ -104,10 +106,10 @@ bool CCudaProjector2D::initialize(const Config& _cfg)  	// TODO: Check the projection geometry is a supported type -	XMLNode* node = _cfg.self->getSingleNode("ProjectionKernel"); +	XMLNode node = _cfg.self.getSingleNode("ProjectionKernel");  	m_projectionKernel = ker2d_default;  	if (node) { -		std::string sProjKernel = node->getContent(); +		std::string sProjKernel = node.getContent();  		if (sProjKernel == "default") { @@ -115,9 +117,14 @@ bool CCudaProjector2D::initialize(const Config& _cfg)  			return false;  		}  	} -	ASTRA_DELETE(node);  	CC.markNodeParsed("ProjectionKernel"); +	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1); +	CC.markOptionParsed("VoxelSuperSampling"); +  +	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1); +	CC.markOptionParsed("DetectorSuperSampling"); +  	m_bIsInitialized = _check();  	return m_bIsInitialized;  } diff --git a/src/CudaProjector3D.cpp b/src/CudaProjector3D.cpp index 2f4c799..d2fd74c 100644 --- a/src/CudaProjector3D.cpp +++ b/src/CudaProjector3D.cpp @@ -62,6 +62,8 @@ void CCudaProjector3D::_clear()  	m_bIsInitialized = false;  	m_projectionKernel = ker3d_default; +	m_iVoxelSuperSampling = 1; +	m_iDetectorSuperSampling = 1;  }  //---------------------------------------------------------------------------------------- @@ -105,10 +107,10 @@ bool CCudaProjector3D::initialize(const Config& _cfg)  		return false;  	} -	XMLNode* node = _cfg.self->getSingleNode("ProjectionKernel"); +	XMLNode node = _cfg.self.getSingleNode("ProjectionKernel");  	m_projectionKernel = ker3d_default;  	if (node) { -		std::string sProjKernel = node->getContent(); +		std::string sProjKernel = node.getContent();  		if (sProjKernel == "default") { @@ -118,9 +120,14 @@ bool CCudaProjector3D::initialize(const Config& _cfg)  			return false;  		}  	} -	ASTRA_DELETE(node);  	CC.markNodeParsed("ProjectionKernel"); +	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1); +	CC.markOptionParsed("VoxelSuperSampling"); +  +	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1); +	CC.markOptionParsed("DetectorSuperSampling"); +  	m_bIsInitialized = _check();  	return m_bIsInitialized;  } diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp index 1c6b763..71b6637 100644 --- a/src/CudaReconstructionAlgorithm2D.cpp +++ b/src/CudaReconstructionAlgorithm2D.cpp @@ -95,96 +95,101 @@ bool CCudaReconstructionAlgorithm2D::initialize(const Config& _cfg)  		clear();  	} +	// Projector +	XMLNode node = _cfg.self.getSingleNode("ProjectorId"); +	CCudaProjector2D* pCudaProjector = 0; +	if (node) { +		int id = boost::lexical_cast<int>(node.getContent()); +		CProjector2D *projector = CProjector2DManager::getSingleton().get(id); +		pCudaProjector = dynamic_cast<CCudaProjector2D*>(projector); +		if (!pCudaProjector) { +			ASTRA_WARN("non-CUDA Projector2D passed"); +		} +	} +	CC.markNodeParsed("ProjectorId"); + +  	// sinogram data -	XMLNode* node = _cfg.self->getSingleNode("ProjectionDataId"); +	node = _cfg.self.getSingleNode("ProjectionDataId");  	ASTRA_CONFIG_CHECK(node, "CudaSirt2", "No ProjectionDataId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ProjectionDataId");  	// reconstruction data -	node = _cfg.self->getSingleNode("ReconstructionDataId"); +	node = _cfg.self.getSingleNode("ReconstructionDataId");  	ASTRA_CONFIG_CHECK(node, "CudaSirt2", "No ReconstructionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pReconstruction = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ReconstructionDataId");  	// fixed mask -	if (_cfg.self->hasOption("ReconstructionMaskId")) { +	if (_cfg.self.hasOption("ReconstructionMaskId")) {  		m_bUseReconstructionMask = true; -		id = boost::lexical_cast<int>(_cfg.self->getOption("ReconstructionMaskId")); +		id = boost::lexical_cast<int>(_cfg.self.getOption("ReconstructionMaskId"));  		m_pReconstructionMask = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));  		ASTRA_CONFIG_CHECK(m_pReconstructionMask, "CudaReconstruction2D", "Invalid ReconstructionMaskId.");  	}  	CC.markOptionParsed("ReconstructionMaskId");  	// fixed mask -	if (_cfg.self->hasOption("SinogramMaskId")) { +	if (_cfg.self.hasOption("SinogramMaskId")) {  		m_bUseSinogramMask = true; -		id = boost::lexical_cast<int>(_cfg.self->getOption("SinogramMaskId")); +		id = boost::lexical_cast<int>(_cfg.self.getOption("SinogramMaskId"));  		m_pSinogramMask = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));  		ASTRA_CONFIG_CHECK(m_pSinogramMask, "CudaReconstruction2D", "Invalid SinogramMaskId.");  	}  	CC.markOptionParsed("SinogramMaskId");  	// Constraints - NEW -	if (_cfg.self->hasOption("MinConstraint")) { +	if (_cfg.self.hasOption("MinConstraint")) {  		m_bUseMinConstraint = true; -		m_fMinValue = _cfg.self->getOptionNumerical("MinConstraint", 0.0f); +		m_fMinValue = _cfg.self.getOptionNumerical("MinConstraint", 0.0f);  		CC.markOptionParsed("MinConstraint");  	} else {  		// Constraint - OLD -		m_bUseMinConstraint = _cfg.self->getOptionBool("UseMinConstraint", false); +		m_bUseMinConstraint = _cfg.self.getOptionBool("UseMinConstraint", false);  		CC.markOptionParsed("UseMinConstraint");  		if (m_bUseMinConstraint) { -			m_fMinValue = _cfg.self->getOptionNumerical("MinConstraintValue", 0.0f); +			m_fMinValue = _cfg.self.getOptionNumerical("MinConstraintValue", 0.0f);  			CC.markOptionParsed("MinConstraintValue");  		}  	} -	if (_cfg.self->hasOption("MaxConstraint")) { +	if (_cfg.self.hasOption("MaxConstraint")) {  		m_bUseMaxConstraint = true; -		m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraint", 255.0f); +		m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraint", 255.0f);  		CC.markOptionParsed("MaxConstraint");  	} else {  		// Constraint - OLD -		m_bUseMaxConstraint = _cfg.self->getOptionBool("UseMaxConstraint", false); +		m_bUseMaxConstraint = _cfg.self.getOptionBool("UseMaxConstraint", false);  		CC.markOptionParsed("UseMaxConstraint");  		if (m_bUseMaxConstraint) { -			m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraintValue", 0.0f); +			m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraintValue", 0.0f);  			CC.markOptionParsed("MaxConstraintValue");  		}  	}  	// GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);  	CC.markOptionParsed("GPUindex"); -	if (!_cfg.self->hasOption("GPUindex")) +	if (!_cfg.self.hasOption("GPUindex"))  		CC.markOptionParsed("GPUIndex"); -	// Detector supersampling factor -	m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); +	// Supersampling factors +	m_iDetectorSuperSampling = 1; +	m_iPixelSuperSampling = 1; +	if (pCudaProjector) { +		// New interface +		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling(); +		m_iPixelSuperSampling = pCudaProjector->getVoxelSuperSampling(); +	} +	// Deprecated options +	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling); +	m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", m_iPixelSuperSampling);  	CC.markOptionParsed("DetectorSuperSampling"); - -	// Pixel supersampling factor -	m_iPixelSuperSampling = (int)_cfg.self->getOptionNumerical("PixelSuperSampling", 1);  	CC.markOptionParsed("PixelSuperSampling"); -	// This isn't used yet, but passing it is not something to warn about -	node = _cfg.self->getSingleNode("ProjectorId"); -	if (node) { -		id = boost::lexical_cast<int>(node->getContent()); -		CProjector2D *projector = CProjector2DManager::getSingleton().get(id); -		if (!dynamic_cast<CCudaProjector2D*>(projector)) { -			ASTRA_WARN("non-CUDA Projector2D passed"); -		} -		delete node; -	} -	CC.markNodeParsed("ProjectorId"); - -  	return _check();  } diff --git a/src/CudaRoiSelectAlgorithm.cpp b/src/CudaRoiSelectAlgorithm.cpp index bfccb3a..7635c69 100644 --- a/src/CudaRoiSelectAlgorithm.cpp +++ b/src/CudaRoiSelectAlgorithm.cpp @@ -66,22 +66,21 @@ bool CCudaRoiSelectAlgorithm::initialize(const Config& _cfg)  	ConfigStackCheck<CAlgorithm> CC("CudaDartMaskAlgorithm", this, _cfg);  	// reconstruction data -	XMLNode* node = _cfg.self->getSingleNode("DataId"); +	XMLNode node = _cfg.self.getSingleNode("DataId");  	ASTRA_CONFIG_CHECK(node, "CudaRoiSelect", "No DataId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pData = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("DataId");  	// Option: GPU number -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUIndex", m_iGPUIndex); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);  	CC.markOptionParsed("GPUindex"); -	if (!_cfg.self->hasOption("GPUindex")) +	if (!_cfg.self.hasOption("GPUindex"))  		CC.markOptionParsed("GPUIndex");  	// Option: Radius -	m_fRadius = (unsigned int)_cfg.self->getOptionNumerical("Radius", 0.0f); +	m_fRadius = (unsigned int)_cfg.self.getOptionNumerical("Radius", 0.0f);  	CC.markOptionParsed("Radius");  	_check(); diff --git a/src/CudaSartAlgorithm.cpp b/src/CudaSartAlgorithm.cpp index 8e22c59..8c0c6d7 100644 --- a/src/CudaSartAlgorithm.cpp +++ b/src/CudaSartAlgorithm.cpp @@ -74,7 +74,7 @@ bool CCudaSartAlgorithm::initialize(const Config& _cfg)  	// projection order  	int projectionCount = m_pSinogram->getGeometry()->getProjectionAngleCount();  	int* projectionOrder = NULL; -	string projOrder = _cfg.self->getOption("ProjectionOrder", "random"); +	string projOrder = _cfg.self.getOption("ProjectionOrder", "random");  	CC.markOptionParsed("ProjectionOrder");  	if (projOrder == "sequential") {  		projectionOrder = new int[projectionCount]; @@ -97,7 +97,7 @@ bool CCudaSartAlgorithm::initialize(const Config& _cfg)  		sart->setProjectionOrder(projectionOrder, projectionCount);  		delete[] projectionOrder;  	} else if (projOrder == "custom") { -		vector<float32> projOrderList = _cfg.self->getOptionNumericalArray("ProjectionOrderList"); +		vector<float32> projOrderList = _cfg.self.getOptionNumericalArray("ProjectionOrderList");  		projectionOrder = new int[projOrderList.size()];  		for (int i = 0; i < projOrderList.size(); i++) {  			projectionOrder[i] = static_cast<int>(projOrderList[i]); diff --git a/src/CudaSirtAlgorithm.cpp b/src/CudaSirtAlgorithm.cpp index f6eb79a..d424915 100644 --- a/src/CudaSirtAlgorithm.cpp +++ b/src/CudaSirtAlgorithm.cpp @@ -76,13 +76,13 @@ bool CCudaSirtAlgorithm::initialize(const Config& _cfg)  		return false;  	// min/max masks -	if (_cfg.self->hasOption("MinMaskId")) { -		int id = boost::lexical_cast<int>(_cfg.self->getOption("MinMaskId")); +	if (_cfg.self.hasOption("MinMaskId")) { +		int id = boost::lexical_cast<int>(_cfg.self.getOption("MinMaskId"));  		m_pMinMask = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));  	}  	CC.markOptionParsed("MinMaskId"); -	if (_cfg.self->hasOption("MaxMaskId")) { -		int id = boost::lexical_cast<int>(_cfg.self->getOption("MaxMaskId")); +	if (_cfg.self.hasOption("MaxMaskId")) { +		int id = boost::lexical_cast<int>(_cfg.self.getOption("MaxMaskId"));  		m_pMaxMask = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));  	}  	CC.markOptionParsed("MaxMaskId"); diff --git a/src/CudaSirtAlgorithm3D.cpp b/src/CudaSirtAlgorithm3D.cpp index d67778f..b833e07 100644 --- a/src/CudaSirtAlgorithm3D.cpp +++ b/src/CudaSirtAlgorithm3D.cpp @@ -36,6 +36,7 @@ $Id$  #include "astra/ParallelProjectionGeometry3D.h"  #include "astra/ParallelVecProjectionGeometry3D.h"  #include "astra/ConeVecProjectionGeometry3D.h" +#include "astra/CudaProjector3D.h"  #include "../cuda/3d/astra3d.h" @@ -107,12 +108,28 @@ bool CCudaSirtAlgorithm3D::initialize(const Config& _cfg)  		return false;  	} -	m_iGPUIndex = (int)_cfg.self->getOptionNumerical("GPUindex", -1); +	CCudaProjector3D* pCudaProjector = 0; +	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector); +	if (!pCudaProjector) { +		// TODO: Report +	} + +	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);  	CC.markOptionParsed("GPUindex"); -	m_iDetectorSuperSampling = (int)_cfg.self->getOptionNumerical("DetectorSuperSampling", 1); -	CC.markOptionParsed("DetectorSuperSampling"); -	m_iVoxelSuperSampling = (int)_cfg.self->getOptionNumerical("VoxelSuperSampling", 1); + + +	m_iVoxelSuperSampling = 1; +	m_iDetectorSuperSampling = 1; +	if (pCudaProjector) { +		// New interface +		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling(); +		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling(); +	} +	// Deprecated options +	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling); +	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);  	CC.markOptionParsed("VoxelSuperSampling"); +	CC.markOptionParsed("DetectorSuperSampling");  	m_pSirt = new AstraSIRT3d(); diff --git a/src/FanFlatProjectionGeometry2D.cpp b/src/FanFlatProjectionGeometry2D.cpp index d757f18..32a19bc 100644 --- a/src/FanFlatProjectionGeometry2D.cpp +++ b/src/FanFlatProjectionGeometry2D.cpp @@ -134,17 +134,15 @@ bool CFanFlatProjectionGeometry2D::initialize(const Config& _cfg)  	CProjectionGeometry2D::initialize(_cfg);  	// Required: DistanceOriginDetector -	XMLNode* node = _cfg.self->getSingleNode("DistanceOriginDetector"); +	XMLNode node = _cfg.self.getSingleNode("DistanceOriginDetector");  	ASTRA_CONFIG_CHECK(node, "FanFlatProjectionGeometry2D", "No DistanceOriginDetector tag specified."); -	m_fOriginDetectorDistance = boost::lexical_cast<float32>(node->getContent()); -	ASTRA_DELETE(node); +	m_fOriginDetectorDistance = boost::lexical_cast<float32>(node.getContent());  	CC.markNodeParsed("DistanceOriginDetector");  	// Required: DetectorOriginSource -	node = _cfg.self->getSingleNode("DistanceOriginSource"); +	node = _cfg.self.getSingleNode("DistanceOriginSource");  	ASTRA_CONFIG_CHECK(node, "FanFlatProjectionGeometry2D", "No DistanceOriginSource tag specified."); -	m_fOriginSourceDistance = boost::lexical_cast<float32>(node->getContent()); -	ASTRA_DELETE(node); +	m_fOriginSourceDistance = boost::lexical_cast<float32>(node.getContent());  	CC.markNodeParsed("DistanceOriginSource");  	// success @@ -209,12 +207,12 @@ Config* CFanFlatProjectionGeometry2D::getConfiguration() const  {  	Config* cfg = new Config();  	cfg->initialize("ProjectionGeometry2D"); -	cfg->self->addAttribute("type", "fanflat"); -	cfg->self->addChildNode("DetectorCount", getDetectorCount()); -	cfg->self->addChildNode("DetectorWidth", getDetectorWidth()); -	cfg->self->addChildNode("DistanceOriginSource", getOriginSourceDistance()); -	cfg->self->addChildNode("DistanceOriginDetector", getOriginDetectorDistance()); -	cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); +	cfg->self.addAttribute("type", "fanflat"); +	cfg->self.addChildNode("DetectorCount", getDetectorCount()); +	cfg->self.addChildNode("DetectorWidth", getDetectorWidth()); +	cfg->self.addChildNode("DistanceOriginSource", getOriginSourceDistance()); +	cfg->self.addChildNode("DistanceOriginDetector", getOriginDetectorDistance()); +	cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);  	return cfg;  }  //---------------------------------------------------------------------------------------- diff --git a/src/FanFlatVecProjectionGeometry2D.cpp b/src/FanFlatVecProjectionGeometry2D.cpp index 9c7b596..4104379 100644 --- a/src/FanFlatVecProjectionGeometry2D.cpp +++ b/src/FanFlatVecProjectionGeometry2D.cpp @@ -116,25 +116,23 @@ bool CFanFlatVecProjectionGeometry2D::initialize(const Config& _cfg)  	ASTRA_ASSERT(_cfg.self);  	ConfigStackCheck<CProjectionGeometry2D> CC("FanFlatVecProjectionGeometry2D", this, _cfg);	 -	XMLNode* node; +	XMLNode node;  	// TODO: Fix up class hierarchy... this class doesn't fit very well.  	// initialization of parent class  	//CProjectionGeometry2D::initialize(_cfg);  	// Required: DetectorCount -	node = _cfg.self->getSingleNode("DetectorCount"); +	node = _cfg.self.getSingleNode("DetectorCount");  	ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry3D", "No DetectorRowCount tag specified."); -	m_iDetectorCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iDetectorCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("DetectorCount");  	// Required: Vectors -	node = _cfg.self->getSingleNode("Vectors"); +	node = _cfg.self.getSingleNode("Vectors");  	ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry3D", "No Vectors tag specified."); -	vector<float32> data = node->getContentNumericalArray(); +	vector<float32> data = node.getContentNumericalArray();  	CC.markNodeParsed("Vectors"); -	ASTRA_DELETE(node);  	ASTRA_CONFIG_CHECK(data.size() % 6 == 0, "FanFlatVecProjectionGeometry3D", "Vectors doesn't consist of 6-tuples.");  	m_iProjectionAngleCount = data.size() / 6;  	m_pProjectionAngles = new SFanProjection[m_iProjectionAngleCount]; @@ -232,8 +230,8 @@ Config* CFanFlatVecProjectionGeometry2D::getConfiguration() const  {  	Config* cfg = new Config();  	cfg->initialize("ProjectionGeometry2D"); -	cfg->self->addAttribute("type", "fanflat_vec"); -	cfg->self->addChildNode("DetectorCount", getDetectorCount()); +	cfg->self.addAttribute("type", "fanflat_vec"); +	cfg->self.addChildNode("DetectorCount", getDetectorCount());  	std::string vectors = "";  	for (int i = 0; i < m_iProjectionAngleCount; ++i) {  		SFanProjection& p = m_pProjectionAngles[i]; @@ -245,7 +243,7 @@ Config* CFanFlatVecProjectionGeometry2D::getConfiguration() const  		vectors += boost::lexical_cast<string>(p.fDetUY);  		if (i < m_iProjectionAngleCount-1) vectors += ';';  	} -	cfg->self->addChildNode("Vectors", vectors); +	cfg->self.addChildNode("Vectors", vectors);  	return cfg;  }  //---------------------------------------------------------------------------------------- diff --git a/src/FilteredBackProjectionAlgorithm.cpp b/src/FilteredBackProjectionAlgorithm.cpp index 4a8e5ac..f494d22 100644 --- a/src/FilteredBackProjectionAlgorithm.cpp +++ b/src/FilteredBackProjectionAlgorithm.cpp @@ -94,30 +94,27 @@ bool CFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)  	ASTRA_ASSERT(_cfg.self);  	// projector -	XMLNode* node = _cfg.self->getSingleNode("ProjectorId"); +	XMLNode node = _cfg.self.getSingleNode("ProjectorId");  	ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectorId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pProjector = CProjector2DManager::getSingleton().get(id); -	ASTRA_DELETE(node);  	// sinogram data -	node = _cfg.self->getSingleNode("ProjectionDataId"); +	node = _cfg.self.getSingleNode("ProjectionDataId");  	ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	// volume data -	node = _cfg.self->getSingleNode("ReconstructionDataId"); +	node = _cfg.self.getSingleNode("ReconstructionDataId");  	ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ReconstructionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pReconstruction = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node); -	node = _cfg.self->getSingleNode("ProjectionIndex"); +	node = _cfg.self.getSingleNode("ProjectionIndex");  	if (node)   	{ -		vector<float32> projectionIndex = node->getContentNumericalArray(); +		vector<float32> projectionIndex = node.getContentNumericalArray();  		int angleCount = projectionIndex.size();  		int detectorCount = m_pProjector->getProjectionGeometry()->getDetectorCount(); @@ -154,7 +151,6 @@ bool CFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)  		m_pProjector = new CParallelBeamLineKernelProjector2D(pg,m_pReconstruction->getGeometry());  		m_pSinogram = new CFloat32ProjectionData2D(pg, sinogramData2D);  	} -	ASTRA_DELETE(node);  	// TODO: check that the angles are linearly spaced between 0 and pi diff --git a/src/ForwardProjectionAlgorithm.cpp b/src/ForwardProjectionAlgorithm.cpp index b530491..f356824 100644 --- a/src/ForwardProjectionAlgorithm.cpp +++ b/src/ForwardProjectionAlgorithm.cpp @@ -126,37 +126,34 @@ bool CForwardProjectionAlgorithm::initialize(const Config& _cfg)  	}  	// projector -	XMLNode* node = _cfg.self->getSingleNode("ProjectorId"); +	XMLNode node = _cfg.self.getSingleNode("ProjectorId");  	ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No ProjectorId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pProjector = CProjector2DManager::getSingleton().get(id); -	ASTRA_DELETE(node);  	// sinogram data -	node = _cfg.self->getSingleNode("ProjectionDataId"); +	node = _cfg.self.getSingleNode("ProjectionDataId");  	ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No ProjectionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	// volume data -	node = _cfg.self->getSingleNode("VolumeDataId"); +	node = _cfg.self.getSingleNode("VolumeDataId");  	ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No VolumeDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pVolume = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	// volume mask -	if (_cfg.self->hasOption("VolumeMaskId")) { +	if (_cfg.self.hasOption("VolumeMaskId")) {  		m_bUseVolumeMask = true; -		id = boost::lexical_cast<int>(_cfg.self->getOption("VolumeMaskId")); +		id = boost::lexical_cast<int>(_cfg.self.getOption("VolumeMaskId"));  		m_pVolumeMask = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));  	}  	// sino mask -	if (_cfg.self->hasOption("SinogramMaskId")) { +	if (_cfg.self.hasOption("SinogramMaskId")) {  		m_bUseSinogramMask = true; -		id = boost::lexical_cast<int>(_cfg.self->getOption("SinogramMaskId")); +		id = boost::lexical_cast<int>(_cfg.self.getOption("SinogramMaskId"));  		m_pSinogramMask = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));  	} diff --git a/src/ParallelBeamBlobKernelProjector2D.cpp b/src/ParallelBeamBlobKernelProjector2D.cpp index 3253f88..4559a48 100644 --- a/src/ParallelBeamBlobKernelProjector2D.cpp +++ b/src/ParallelBeamBlobKernelProjector2D.cpp @@ -128,28 +128,28 @@ bool CParallelBeamBlobKernelProjector2D::initialize(const Config& _cfg)  	}  	// required: Kernel -	XMLNode* node = _cfg.self->getSingleNode("Kernel"); +	XMLNode node = _cfg.self.getSingleNode("Kernel");  	ASTRA_CONFIG_CHECK(node, "BlobProjector", "No Kernel tag specified.");  	{  		// Required: KernelSize -		XMLNode* node2 = node->getSingleNode("KernelSize"); +		XMLNode node2 = node.getSingleNode("KernelSize");  		ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/KernelSize tag specified."); -		m_fBlobSize = boost::lexical_cast<float32>(node2->getContent()); +		m_fBlobSize = boost::lexical_cast<float32>(node2.getContent());  		// Required: SampleRate -		node2 = node->getSingleNode("SampleRate"); +		node2 = node.getSingleNode("SampleRate");  		ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/SampleRate tag specified."); -		m_fBlobSampleRate = boost::lexical_cast<float32>(node2->getContent()); +		m_fBlobSampleRate = boost::lexical_cast<float32>(node2.getContent());  		// Required: SampleCount -		node2 = node->getSingleNode("SampleCount"); +		node2 = node.getSingleNode("SampleCount");  		ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/SampleCount tag specified."); -		m_iBlobSampleCount = boost::lexical_cast<int>(node2->getContent()); +		m_iBlobSampleCount = boost::lexical_cast<int>(node2.getContent());  		// Required: KernelValues -		node2 = node->getSingleNode("KernelValues"); +		node2 = node.getSingleNode("KernelValues");  		ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/KernelValues tag specified."); -		vector<float32> values = node2->getContentNumericalArray(); +		vector<float32> values = node2.getContentNumericalArray();  		ASTRA_CONFIG_CHECK(values.size() == (unsigned int)m_iBlobSampleCount, "BlobProjector", "Number of specified values doesn't match SampleCount.");  		m_pfBlobValues = new float32[m_iBlobSampleCount];  		for (int i = 0; i < m_iBlobSampleCount; i++) { @@ -157,9 +157,9 @@ bool CParallelBeamBlobKernelProjector2D::initialize(const Config& _cfg)  		}  		// Required: KernelValues -		node2 = node->getSingleNode("KernelValuesNeg"); +		node2 = node.getSingleNode("KernelValuesNeg");  		ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/KernelValuesNeg tag specified."); -		vector<float32> values2 = node2->getContentNumericalArray(); +		vector<float32> values2 = node2.getContentNumericalArray();  		ASTRA_CONFIG_CHECK(values2.size() == (unsigned int)m_iBlobSampleCount, "BlobProjector", "Number of specified values doesn't match SampleCount.");  		m_pfBlobValuesNeg = new float32[m_iBlobSampleCount];  		for (int i = 0; i < m_iBlobSampleCount; i++) { diff --git a/src/ParallelProjectionGeometry2D.cpp b/src/ParallelProjectionGeometry2D.cpp index cac8f30..7260b83 100644 --- a/src/ParallelProjectionGeometry2D.cpp +++ b/src/ParallelProjectionGeometry2D.cpp @@ -176,10 +176,15 @@ Config* CParallelProjectionGeometry2D::getConfiguration() const  {  	Config* cfg = new Config();  	cfg->initialize("ProjectionGeometry2D"); -	cfg->self->addAttribute("type", "parallel"); -	cfg->self->addChildNode("DetectorCount", getDetectorCount()); -	cfg->self->addChildNode("DetectorWidth", getDetectorWidth()); -	cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); +	cfg->self.addAttribute("type", "parallel"); +	cfg->self.addChildNode("DetectorCount", getDetectorCount()); +	cfg->self.addChildNode("DetectorWidth", getDetectorWidth()); +	cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); +	if(m_pfExtraDetectorOffset!=NULL){ +		XMLNode opt = cfg->self.addChildNode("Option"); +		opt.addAttribute("key","ExtraDetectorOffset"); +		opt.setContent(m_pfExtraDetectorOffset, m_iProjectionAngleCount); +	}  	return cfg;  }  //---------------------------------------------------------------------------------------- diff --git a/src/ParallelProjectionGeometry3D.cpp b/src/ParallelProjectionGeometry3D.cpp index eb200f9..1c87157 100644 --- a/src/ParallelProjectionGeometry3D.cpp +++ b/src/ParallelProjectionGeometry3D.cpp @@ -164,12 +164,12 @@ Config* CParallelProjectionGeometry3D::getConfiguration() const  {  	Config* cfg = new Config();  	cfg->initialize("ProjectionGeometry3D"); -	cfg->self->addAttribute("type", "parallel3d"); -	cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); -	cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); -	cfg->self->addChildNode("DetectorSpacingX", m_fDetectorSpacingX); -	cfg->self->addChildNode("DetectorSpacingY", m_fDetectorSpacingY); -	cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); +	cfg->self.addAttribute("type", "parallel3d"); +	cfg->self.addChildNode("DetectorRowCount", m_iDetectorRowCount); +	cfg->self.addChildNode("DetectorColCount", m_iDetectorColCount); +	cfg->self.addChildNode("DetectorSpacingX", m_fDetectorSpacingX); +	cfg->self.addChildNode("DetectorSpacingY", m_fDetectorSpacingY); +	cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);  	return cfg;  }  //---------------------------------------------------------------------------------------- diff --git a/src/ParallelVecProjectionGeometry3D.cpp b/src/ParallelVecProjectionGeometry3D.cpp index dc325e9..ffad6d0 100644 --- a/src/ParallelVecProjectionGeometry3D.cpp +++ b/src/ParallelVecProjectionGeometry3D.cpp @@ -73,33 +73,30 @@ bool CParallelVecProjectionGeometry3D::initialize(const Config& _cfg)  	ASTRA_ASSERT(_cfg.self);  	ConfigStackCheck<CProjectionGeometry3D> CC("ParallelVecProjectionGeometry3D", this, _cfg);	 -	XMLNode* node; +	XMLNode node;  	// TODO: Fix up class hierarchy... this class doesn't fit very well.  	// initialization of parent class  	//CProjectionGeometry3D::initialize(_cfg);  	// Required: DetectorRowCount -	node = _cfg.self->getSingleNode("DetectorRowCount"); +	node = _cfg.self.getSingleNode("DetectorRowCount");  	ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry3D", "No DetectorRowCount tag specified."); -	m_iDetectorRowCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iDetectorRowCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("DetectorRowCount");  	// Required: DetectorCount -	node = _cfg.self->getSingleNode("DetectorColCount"); +	node = _cfg.self.getSingleNode("DetectorColCount");  	ASTRA_CONFIG_CHECK(node, "", "No DetectorColCount tag specified."); -	m_iDetectorColCount = boost::lexical_cast<int>(node->getContent()); +	m_iDetectorColCount = boost::lexical_cast<int>(node.getContent());  	m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; -	ASTRA_DELETE(node);  	CC.markNodeParsed("DetectorColCount");  	// Required: Vectors -	node = _cfg.self->getSingleNode("Vectors"); +	node = _cfg.self.getSingleNode("Vectors");  	ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry3D", "No Vectors tag specified."); -	vector<double> data = node->getContentNumericalArrayDouble(); +	vector<double> data = node.getContentNumericalArrayDouble();  	CC.markNodeParsed("Vectors"); -	ASTRA_DELETE(node);  	ASTRA_CONFIG_CHECK(data.size() % 12 == 0, "ParallelVecProjectionGeometry3D", "Vectors doesn't consist of 12-tuples.");  	m_iProjectionAngleCount = data.size() / 12;  	m_pProjectionAngles = new SPar3DProjection[m_iProjectionAngleCount]; @@ -208,9 +205,9 @@ Config* CParallelVecProjectionGeometry3D::getConfiguration() const  	Config* cfg = new Config();  	cfg->initialize("ProjectionGeometry3D"); -	cfg->self->addAttribute("type", "parallel3d_vec"); -	cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); -	cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); +	cfg->self.addAttribute("type", "parallel3d_vec"); +	cfg->self.addChildNode("DetectorRowCount", m_iDetectorRowCount); +	cfg->self.addChildNode("DetectorColCount", m_iDetectorColCount);  	std::string vectors = "";  	for (int i = 0; i < m_iProjectionAngleCount; ++i) { @@ -229,7 +226,7 @@ Config* CParallelVecProjectionGeometry3D::getConfiguration() const  		vectors += boost::lexical_cast<string>(p.fDetVZ);  		if (i < m_iProjectionAngleCount-1) vectors += ';';  	} -	cfg->self->addChildNode("Vectors", vectors); +	cfg->self.addChildNode("Vectors", vectors);  	return cfg;  } diff --git a/src/ProjectionGeometry2D.cpp b/src/ProjectionGeometry2D.cpp index 89b5fe0..b89605b 100644 --- a/src/ProjectionGeometry2D.cpp +++ b/src/ProjectionGeometry2D.cpp @@ -124,24 +124,21 @@ bool CProjectionGeometry2D::initialize(const Config& _cfg)  	}  	// Required: DetectorWidth -	XMLNode* node = _cfg.self->getSingleNode("DetectorWidth"); +	XMLNode node = _cfg.self.getSingleNode("DetectorWidth");  	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorWidth tag specified."); -	m_fDetectorWidth = boost::lexical_cast<float32>(node->getContent()); -	ASTRA_DELETE(node); +	m_fDetectorWidth = boost::lexical_cast<float32>(node.getContent());  	CC.markNodeParsed("DetectorWidth");  	// Required: DetectorCount -	node = _cfg.self->getSingleNode("DetectorCount"); +	node = _cfg.self.getSingleNode("DetectorCount");  	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorCount tag specified."); -	m_iDetectorCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iDetectorCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("DetectorCount");  	// Required: ProjectionAngles -	node = _cfg.self->getSingleNode("ProjectionAngles"); +	node = _cfg.self.getSingleNode("ProjectionAngles");  	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No ProjectionAngles tag specified."); -	vector<float32> angles = node->getContentNumericalArray(); -	delete node; +	vector<float32> angles = node.getContentNumericalArray();  	m_iProjectionAngleCount = angles.size();  	ASTRA_CONFIG_CHECK(m_iProjectionAngleCount > 0, "ProjectionGeometry2D", "Not enough ProjectionAngles specified.");  	m_pfProjectionAngles = new float32[m_iProjectionAngleCount]; @@ -150,7 +147,7 @@ bool CProjectionGeometry2D::initialize(const Config& _cfg)  	}  	CC.markNodeParsed("ProjectionAngles"); -	vector<float32> offset = _cfg.self->getOptionNumericalArray("ExtraDetectorOffset"); +	vector<float32> offset = _cfg.self.getOptionNumericalArray("ExtraDetectorOffset");  	m_pfExtraDetectorOffset = new float32[m_iProjectionAngleCount];  	if (offset.size() == (size_t)m_iProjectionAngleCount) {  		for (int i = 0; i < m_iProjectionAngleCount; i++) { diff --git a/src/ProjectionGeometry3D.cpp b/src/ProjectionGeometry3D.cpp index 5b77767..ef0246c 100644 --- a/src/ProjectionGeometry3D.cpp +++ b/src/ProjectionGeometry3D.cpp @@ -149,38 +149,34 @@ bool CProjectionGeometry3D::initialize(const Config& _cfg)  	ASTRA_ASSERT(_cfg.self);  	// Required: DetectorWidth -	XMLNode* node = _cfg.self->getSingleNode("DetectorSpacingX"); +	XMLNode node = _cfg.self.getSingleNode("DetectorSpacingX");  	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingX tag specified."); -	m_fDetectorSpacingX = boost::lexical_cast<float32>(node->getContent()); -	ASTRA_DELETE(node); +	m_fDetectorSpacingX = boost::lexical_cast<float32>(node.getContent());  	CC.markNodeParsed("DetectorSpacingX");  	// Required: DetectorHeight -	node = _cfg.self->getSingleNode("DetectorSpacingY"); +	node = _cfg.self.getSingleNode("DetectorSpacingY");  	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingY tag specified."); -	m_fDetectorSpacingY = boost::lexical_cast<float32>(node->getContent()); -	ASTRA_DELETE(node); +	m_fDetectorSpacingY = boost::lexical_cast<float32>(node.getContent());  	CC.markNodeParsed("DetectorSpacingY");  	// Required: DetectorRowCount -	node = _cfg.self->getSingleNode("DetectorRowCount"); +	node = _cfg.self.getSingleNode("DetectorRowCount");  	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorRowCount tag specified."); -	m_iDetectorRowCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iDetectorRowCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("DetectorRowCount");  	// Required: DetectorCount -	node = _cfg.self->getSingleNode("DetectorColCount"); +	node = _cfg.self.getSingleNode("DetectorColCount");  	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorColCount tag specified."); -	m_iDetectorColCount = boost::lexical_cast<int>(node->getContent()); +	m_iDetectorColCount = boost::lexical_cast<int>(node.getContent());  	m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; -	ASTRA_DELETE(node);  	CC.markNodeParsed("DetectorColCount");  	// Required: ProjectionAngles -	node = _cfg.self->getSingleNode("ProjectionAngles"); +	node = _cfg.self.getSingleNode("ProjectionAngles");  	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No ProjectionAngles tag specified."); -	vector<float32> angles = node->getContentNumericalArray(); +	vector<float32> angles = node.getContentNumericalArray();  	m_iProjectionAngleCount = angles.size();  	ASTRA_CONFIG_CHECK(m_iProjectionAngleCount > 0, "ProjectionGeometry3D", "Not enough ProjectionAngles specified.");  	m_pfProjectionAngles = new float32[m_iProjectionAngleCount]; @@ -188,7 +184,6 @@ bool CProjectionGeometry3D::initialize(const Config& _cfg)  		m_pfProjectionAngles[i] = angles[i];  	}  	CC.markNodeParsed("ProjectionAngles"); -	ASTRA_DELETE(node);  	// Interface class, so don't return true  	return false; diff --git a/src/Projector2D.cpp b/src/Projector2D.cpp index 32a2956..cf233a0 100644 --- a/src/Projector2D.cpp +++ b/src/Projector2D.cpp @@ -114,12 +114,12 @@ bool CProjector2D::initialize(const Config& _cfg)  	}  	// required: ProjectionGeometry -	XMLNode* node = _cfg.self->getSingleNode("ProjectionGeometry"); +	XMLNode node = _cfg.self.getSingleNode("ProjectionGeometry");  	ASTRA_CONFIG_CHECK(node, "Projector2D", "No ProjectionGeometry tag specified.");  	// FIXME: Change how the base class is created. (This is duplicated  	// in astra_mex_data2d.cpp.) -	std::string type = node->getAttribute("type"); +	std::string type = node.getAttribute("type");  	if (type == "sparse_matrix") {  		m_pProjectionGeometry = new CSparseMatrixProjectionGeometry2D();  		m_pProjectionGeometry->initialize(Config(node)); @@ -141,7 +141,7 @@ bool CProjector2D::initialize(const Config& _cfg)  	// required: VolumeGeometry -	node = _cfg.self->getSingleNode("VolumeGeometry"); +	node = _cfg.self.getSingleNode("VolumeGeometry");  	ASTRA_CONFIG_CHECK(node, "Projector2D", "No VolumeGeometry tag specified.");  	m_pVolumeGeometry = new CVolumeGeometry2D();  	m_pVolumeGeometry->initialize(Config(node)); diff --git a/src/Projector3D.cpp b/src/Projector3D.cpp index 14cb16a..5e22105 100644 --- a/src/Projector3D.cpp +++ b/src/Projector3D.cpp @@ -92,11 +92,11 @@ bool CProjector3D::initialize(const Config& _cfg)  	assert(_cfg.self);  	ConfigStackCheck<CProjector3D> CC("Projector3D", this, _cfg); -	XMLNode* node; +	XMLNode node; -	node = _cfg.self->getSingleNode("ProjectionGeometry"); +	node = _cfg.self.getSingleNode("ProjectionGeometry");  	ASTRA_CONFIG_CHECK(node, "Projector3D", "No ProjectionGeometry tag specified."); -	std::string type = node->getAttribute("type"); +	std::string type = node.getAttribute("type");  	CProjectionGeometry3D* pProjGeometry = 0;  	if (type == "parallel3d") {  		pProjGeometry = new CParallelProjectionGeometry3D(); @@ -115,7 +115,7 @@ bool CProjector3D::initialize(const Config& _cfg)  	ASTRA_CONFIG_CHECK(m_pProjectionGeometry->isInitialized(), "Projector3D", "ProjectionGeometry not initialized.");  	CC.markNodeParsed("ProjectionGeometry"); -	node = _cfg.self->getSingleNode("VolumeGeometry"); +	node = _cfg.self.getSingleNode("VolumeGeometry");  	ASTRA_CONFIG_CHECK(node, "Projector3D", "No VolumeGeometry tag specified.");  	CVolumeGeometry3D* pVolGeometry = new CVolumeGeometry3D();  	pVolGeometry->initialize(Config(node)); // this deletes node diff --git a/src/ReconstructionAlgorithm2D.cpp b/src/ReconstructionAlgorithm2D.cpp index e089fac..767efe6 100644 --- a/src/ReconstructionAlgorithm2D.cpp +++ b/src/ReconstructionAlgorithm2D.cpp @@ -84,71 +84,68 @@ bool CReconstructionAlgorithm2D::initialize(const Config& _cfg)  	ConfigStackCheck<CAlgorithm> CC("ReconstructionAlgorithm2D", this, _cfg);  	// projector -	XMLNode* node = _cfg.self->getSingleNode("ProjectorId"); +	XMLNode node = _cfg.self.getSingleNode("ProjectorId");  	ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectorId tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pProjector = CProjector2DManager::getSingleton().get(id); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ProjectorId");  	// sinogram data -	node = _cfg.self->getSingleNode("ProjectionDataId"); +	node = _cfg.self.getSingleNode("ProjectionDataId");  	ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ProjectionDataId");  	// reconstruction data -	node = _cfg.self->getSingleNode("ReconstructionDataId"); +	node = _cfg.self.getSingleNode("ReconstructionDataId");  	ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ReconstructionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pReconstruction = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ReconstructionDataId");  	// fixed mask -	if (_cfg.self->hasOption("ReconstructionMaskId")) { +	if (_cfg.self.hasOption("ReconstructionMaskId")) {  		m_bUseReconstructionMask = true; -		id = boost::lexical_cast<int>(_cfg.self->getOption("ReconstructionMaskId")); +		id = boost::lexical_cast<int>(_cfg.self.getOption("ReconstructionMaskId"));  		m_pReconstructionMask = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));  		ASTRA_CONFIG_CHECK(m_pReconstructionMask, "Reconstruction2D", "Invalid ReconstructionMaskId.");  	}  	CC.markOptionParsed("ReconstructionMaskId");  	// fixed mask -	if (_cfg.self->hasOption("SinogramMaskId")) { +	if (_cfg.self.hasOption("SinogramMaskId")) {  		m_bUseSinogramMask = true; -		id = boost::lexical_cast<int>(_cfg.self->getOption("SinogramMaskId")); +		id = boost::lexical_cast<int>(_cfg.self.getOption("SinogramMaskId"));  		m_pSinogramMask = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));  		ASTRA_CONFIG_CHECK(m_pSinogramMask, "Reconstruction2D", "Invalid SinogramMaskId.");  	}  	CC.markOptionParsed("SinogramMaskId");  	// Constraints - NEW -	if (_cfg.self->hasOption("MinConstraint")) { +	if (_cfg.self.hasOption("MinConstraint")) {  		m_bUseMinConstraint = true; -		m_fMinValue = _cfg.self->getOptionNumerical("MinConstraint", 0.0f); +		m_fMinValue = _cfg.self.getOptionNumerical("MinConstraint", 0.0f);  		CC.markOptionParsed("MinConstraint");  	} else {  		// Constraint - OLD -		m_bUseMinConstraint = _cfg.self->getOptionBool("UseMinConstraint", false); +		m_bUseMinConstraint = _cfg.self.getOptionBool("UseMinConstraint", false);  		CC.markOptionParsed("UseMinConstraint");  		if (m_bUseMinConstraint) { -			m_fMinValue = _cfg.self->getOptionNumerical("MinConstraintValue", 0.0f); +			m_fMinValue = _cfg.self.getOptionNumerical("MinConstraintValue", 0.0f);  			CC.markOptionParsed("MinConstraintValue");  		}  	} -	if (_cfg.self->hasOption("MaxConstraint")) { +	if (_cfg.self.hasOption("MaxConstraint")) {  		m_bUseMaxConstraint = true; -		m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraint", 255.0f); +		m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraint", 255.0f);  		CC.markOptionParsed("MaxConstraint");  	} else {  		// Constraint - OLD -		m_bUseMaxConstraint = _cfg.self->getOptionBool("UseMaxConstraint", false); +		m_bUseMaxConstraint = _cfg.self.getOptionBool("UseMaxConstraint", false);  		CC.markOptionParsed("UseMaxConstraint");  		if (m_bUseMaxConstraint) { -			m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraintValue", 0.0f); +			m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraintValue", 0.0f);  			CC.markOptionParsed("MaxConstraintValue");  		}  	} diff --git a/src/ReconstructionAlgorithm3D.cpp b/src/ReconstructionAlgorithm3D.cpp index 13d069d..f975ace 100644 --- a/src/ReconstructionAlgorithm3D.cpp +++ b/src/ReconstructionAlgorithm3D.cpp @@ -104,72 +104,74 @@ bool CReconstructionAlgorithm3D::initialize(const Config& _cfg)  	ASTRA_ASSERT(_cfg.self);  	ConfigStackCheck<CAlgorithm> CC("ReconstructionAlgorithm3D", this, _cfg); -	XMLNode* node; +	XMLNode node;  	int id; -#if 0 +  	// projector -	node = _cfg.self->getSingleNode("ProjectorId"); -	ASTRA_CONFIG_CHECK(node, "Reconstruction3D", "No ProjectorId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); -	m_pProjector = CProjector3DManager::getSingleton().get(id); -	ASTRA_DELETE(node); -#endif +	node = _cfg.self.getSingleNode("ProjectorId"); +	m_pProjector = 0; +	if (node) { +		id = boost::lexical_cast<int>(node.getContent()); +		m_pProjector = CProjector3DManager::getSingleton().get(id); +		if (!m_pProjector) { +			// TODO: Report +		} +	} +	CC.markNodeParsed("ProjectorId");  	// sinogram data -	node = _cfg.self->getSingleNode("ProjectionDataId"); +	node = _cfg.self.getSingleNode("ProjectionDataId");  	ASTRA_CONFIG_CHECK(node, "Reconstruction3D", "No ProjectionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pSinogram = dynamic_cast<CFloat32ProjectionData3D*>(CData3DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ProjectionDataId");  	// reconstruction data -	node = _cfg.self->getSingleNode("ReconstructionDataId"); +	node = _cfg.self.getSingleNode("ReconstructionDataId");  	ASTRA_CONFIG_CHECK(node, "Reconstruction3D", "No ReconstructionDataId tag specified."); -	id = boost::lexical_cast<int>(node->getContent()); +	id = boost::lexical_cast<int>(node.getContent());  	m_pReconstruction = dynamic_cast<CFloat32VolumeData3D*>(CData3DManager::getSingleton().get(id)); -	ASTRA_DELETE(node);  	CC.markNodeParsed("ReconstructionDataId");  	// fixed mask -	if (_cfg.self->hasOption("ReconstructionMaskId")) { +	if (_cfg.self.hasOption("ReconstructionMaskId")) {  		m_bUseReconstructionMask = true; -		id = boost::lexical_cast<int>(_cfg.self->getOption("ReconstructionMaskId")); +		id = boost::lexical_cast<int>(_cfg.self.getOption("ReconstructionMaskId"));  		m_pReconstructionMask = dynamic_cast<CFloat32VolumeData3D*>(CData3DManager::getSingleton().get(id));  	}  	CC.markOptionParsed("ReconstructionMaskId");  	// fixed mask -	if (_cfg.self->hasOption("SinogramMaskId")) { +	if (_cfg.self.hasOption("SinogramMaskId")) {  		m_bUseSinogramMask = true; -		id = boost::lexical_cast<int>(_cfg.self->getOption("SinogramMaskId")); +		id = boost::lexical_cast<int>(_cfg.self.getOption("SinogramMaskId"));  		m_pSinogramMask = dynamic_cast<CFloat32ProjectionData3D*>(CData3DManager::getSingleton().get(id));  	}  	// Constraints - NEW -	if (_cfg.self->hasOption("MinConstraint")) { +	if (_cfg.self.hasOption("MinConstraint")) {  		m_bUseMinConstraint = true; -		m_fMinValue = _cfg.self->getOptionNumerical("MinConstraint", 0.0f); +		m_fMinValue = _cfg.self.getOptionNumerical("MinConstraint", 0.0f);  		CC.markOptionParsed("MinConstraint");  	} else {  		// Constraint - OLD -		m_bUseMinConstraint = _cfg.self->getOptionBool("UseMinConstraint", false); +		m_bUseMinConstraint = _cfg.self.getOptionBool("UseMinConstraint", false);  		CC.markOptionParsed("UseMinConstraint");  		if (m_bUseMinConstraint) { -			m_fMinValue = _cfg.self->getOptionNumerical("MinConstraintValue", 0.0f); +			m_fMinValue = _cfg.self.getOptionNumerical("MinConstraintValue", 0.0f);  			CC.markOptionParsed("MinConstraintValue");  		}  	} -	if (_cfg.self->hasOption("MaxConstraint")) { +	if (_cfg.self.hasOption("MaxConstraint")) {  		m_bUseMaxConstraint = true; -		m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraint", 255.0f); +		m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraint", 255.0f);  		CC.markOptionParsed("MaxConstraint");  	} else {  		// Constraint - OLD -		m_bUseMaxConstraint = _cfg.self->getOptionBool("UseMaxConstraint", false); +		m_bUseMaxConstraint = _cfg.self.getOptionBool("UseMaxConstraint", false);  		CC.markOptionParsed("UseMaxConstraint");  		if (m_bUseMaxConstraint) { -			m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraintValue", 0.0f); +			m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraintValue", 0.0f);  			CC.markOptionParsed("MaxConstraintValue");  		}  	} diff --git a/src/SartAlgorithm.cpp b/src/SartAlgorithm.cpp index f7a1677..e4dc5c7 100644 --- a/src/SartAlgorithm.cpp +++ b/src/SartAlgorithm.cpp @@ -126,7 +126,7 @@ bool CSartAlgorithm::initialize(const Config& _cfg)  	// projection order  	m_iCurrentProjection = 0;  	m_iProjectionCount = m_pProjector->getProjectionGeometry()->getProjectionAngleCount(); -	string projOrder = _cfg.self->getOption("ProjectionOrder", "sequential"); +	string projOrder = _cfg.self.getOption("ProjectionOrder", "sequential");  	CC.markOptionParsed("ProjectionOrder");  	if (projOrder == "sequential") {  		m_piProjectionOrder = new int[m_iProjectionCount]; @@ -145,7 +145,7 @@ bool CSartAlgorithm::initialize(const Config& _cfg)  			m_piProjectionOrder[i + k] = t;  		}  	} else if (projOrder == "custom") { -		vector<float32> projOrderList = _cfg.self->getOptionNumericalArray("ProjectionOrderList"); +		vector<float32> projOrderList = _cfg.self.getOptionNumericalArray("ProjectionOrderList");  		m_piProjectionOrder = new int[projOrderList.size()];  		for (int i = 0; i < m_iProjectionCount; i++) {  			m_piProjectionOrder[i] = static_cast<int>(projOrderList[i]); diff --git a/src/SparseMatrixProjectionGeometry2D.cpp b/src/SparseMatrixProjectionGeometry2D.cpp index 86357d2..073720f 100644 --- a/src/SparseMatrixProjectionGeometry2D.cpp +++ b/src/SparseMatrixProjectionGeometry2D.cpp @@ -98,11 +98,10 @@ bool CSparseMatrixProjectionGeometry2D::initialize(const Config& _cfg)  	CProjectionGeometry2D::initialize(_cfg);  	// get matrix -	XMLNode* node = _cfg.self->getSingleNode("MatrixID"); +	XMLNode node = _cfg.self.getSingleNode("MatrixID");  	ASTRA_CONFIG_CHECK(node, "SparseMatrixProjectionGeometry2D", "No MatrixID tag specified."); -	int id = boost::lexical_cast<int>(node->getContent()); +	int id = boost::lexical_cast<int>(node.getContent());  	m_pMatrix = CMatrixManager::getSingleton().get(id); -	ASTRA_DELETE(node);  	CC.markNodeParsed("MatrixID");  	// success @@ -194,11 +193,11 @@ Config* CSparseMatrixProjectionGeometry2D::getConfiguration() const  {  	Config* cfg = new Config();  	cfg->initialize("ProjectionGeometry2D"); -	cfg->self->addAttribute("type", "sparse matrix"); -	cfg->self->addChildNode("DetectorCount", getDetectorCount()); -	cfg->self->addChildNode("DetectorWidth", getDetectorWidth()); -	cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); -	cfg->self->addChildNode("MatrixID", CMatrixManager::getSingleton().getIndex(m_pMatrix)); +	cfg->self.addAttribute("type", "sparse matrix"); +	cfg->self.addChildNode("DetectorCount", getDetectorCount()); +	cfg->self.addChildNode("DetectorWidth", getDetectorWidth()); +	cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); +	cfg->self.addChildNode("MatrixID", CMatrixManager::getSingleton().getIndex(m_pMatrix));  	return cfg;  } diff --git a/src/VolumeGeometry2D.cpp b/src/VolumeGeometry2D.cpp index d412914..6eea1b2 100644 --- a/src/VolumeGeometry2D.cpp +++ b/src/VolumeGeometry2D.cpp @@ -164,24 +164,22 @@ bool CVolumeGeometry2D::initialize(const Config& _cfg)  	}  	// Required: GridColCount -	XMLNode* node = _cfg.self->getSingleNode("GridColCount"); +	XMLNode node = _cfg.self.getSingleNode("GridColCount");  	ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridColCount tag specified."); -	m_iGridColCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iGridColCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("GridColCount");  	// Required: GridRowCount -	node = _cfg.self->getSingleNode("GridRowCount"); +	node = _cfg.self.getSingleNode("GridRowCount");  	ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridRowCount tag specified."); -	m_iGridRowCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iGridRowCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("GridRowCount");  	// Optional: Window minima and maxima -	m_fWindowMinX = _cfg.self->getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f); -	m_fWindowMaxX = _cfg.self->getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f); -	m_fWindowMinY = _cfg.self->getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f); -	m_fWindowMaxY = _cfg.self->getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f); +	m_fWindowMinX = _cfg.self.getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f); +	m_fWindowMaxX = _cfg.self.getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f); +	m_fWindowMinY = _cfg.self.getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f); +	m_fWindowMaxY = _cfg.self.getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f);  	CC.markOptionParsed("WindowMinX");  	CC.markOptionParsed("WindowMaxX");  	CC.markOptionParsed("WindowMinY"); @@ -285,13 +283,13 @@ Config* CVolumeGeometry2D::getConfiguration() const  	Config* cfg = new Config();  	cfg->initialize("VolumeGeometry2D"); -	cfg->self->addChildNode("GridColCount", m_iGridColCount); -	cfg->self->addChildNode("GridRowCount", m_iGridRowCount); +	cfg->self.addChildNode("GridColCount", m_iGridColCount); +	cfg->self.addChildNode("GridRowCount", m_iGridRowCount); -	cfg->self->addOption("WindowMinX", m_fWindowMinX); -	cfg->self->addOption("WindowMaxX", m_fWindowMaxX); -	cfg->self->addOption("WindowMinY", m_fWindowMinY); -	cfg->self->addOption("WindowMaxY", m_fWindowMaxY); +	cfg->self.addOption("WindowMinX", m_fWindowMinX); +	cfg->self.addOption("WindowMaxX", m_fWindowMaxX); +	cfg->self.addOption("WindowMinY", m_fWindowMinY); +	cfg->self.addOption("WindowMaxY", m_fWindowMaxY);  	return cfg;  } diff --git a/src/VolumeGeometry3D.cpp b/src/VolumeGeometry3D.cpp index 66e6f0c..a1cf424 100644 --- a/src/VolumeGeometry3D.cpp +++ b/src/VolumeGeometry3D.cpp @@ -192,33 +192,30 @@ bool CVolumeGeometry3D::initialize(const Config& _cfg)  	}  	// Required: GridColCount -	XMLNode* node = _cfg.self->getSingleNode("GridColCount"); +	XMLNode node = _cfg.self.getSingleNode("GridColCount");  	ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridColCount tag specified."); -	m_iGridColCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iGridColCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("GridColCount");  	// Required: GridRowCount -	node = _cfg.self->getSingleNode("GridRowCount"); +	node = _cfg.self.getSingleNode("GridRowCount");  	ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridRowCount tag specified."); -	m_iGridRowCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iGridRowCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("GridRowCount");  	// Required: GridRowCount -	node = _cfg.self->getSingleNode("GridSliceCount"); +	node = _cfg.self.getSingleNode("GridSliceCount");  	ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridSliceCount tag specified."); -	m_iGridSliceCount = boost::lexical_cast<int>(node->getContent()); -	ASTRA_DELETE(node); +	m_iGridSliceCount = boost::lexical_cast<int>(node.getContent());  	CC.markNodeParsed("GridSliceCount");  	// Optional: Window minima and maxima -	m_fWindowMinX = _cfg.self->getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f); -	m_fWindowMaxX = _cfg.self->getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f); -	m_fWindowMinY = _cfg.self->getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f); -	m_fWindowMaxY = _cfg.self->getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f); -	m_fWindowMinZ = _cfg.self->getOptionNumerical("WindowMinZ", -m_iGridSliceCount/2.0f); -	m_fWindowMaxZ = _cfg.self->getOptionNumerical("WindowMaxZ", m_iGridSliceCount/2.0f); +	m_fWindowMinX = _cfg.self.getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f); +	m_fWindowMaxX = _cfg.self.getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f); +	m_fWindowMinY = _cfg.self.getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f); +	m_fWindowMaxY = _cfg.self.getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f); +	m_fWindowMinZ = _cfg.self.getOptionNumerical("WindowMinZ", -m_iGridSliceCount/2.0f); +	m_fWindowMaxZ = _cfg.self.getOptionNumerical("WindowMaxZ", m_iGridSliceCount/2.0f);  	CC.markOptionParsed("WindowMinX");  	CC.markOptionParsed("WindowMaxX");  	CC.markOptionParsed("WindowMinY"); @@ -386,16 +383,16 @@ Config* CVolumeGeometry3D::getConfiguration() const  	Config* cfg = new Config();  	cfg->initialize("VolumeGeometry3D"); -	cfg->self->addChildNode("GridColCount", m_iGridColCount); -	cfg->self->addChildNode("GridRowCount", m_iGridRowCount); -	cfg->self->addChildNode("GridSliceCount", m_iGridSliceCount); +	cfg->self.addChildNode("GridColCount", m_iGridColCount); +	cfg->self.addChildNode("GridRowCount", m_iGridRowCount); +	cfg->self.addChildNode("GridSliceCount", m_iGridSliceCount); -	cfg->self->addOption("WindowMinX", m_fWindowMinX); -	cfg->self->addOption("WindowMaxX", m_fWindowMaxX); -	cfg->self->addOption("WindowMinY", m_fWindowMinY); -	cfg->self->addOption("WindowMaxY", m_fWindowMaxY); -	cfg->self->addOption("WindowMinZ", m_fWindowMinZ); -	cfg->self->addOption("WindowMaxZ", m_fWindowMaxZ); +	cfg->self.addOption("WindowMinX", m_fWindowMinX); +	cfg->self.addOption("WindowMaxX", m_fWindowMaxX); +	cfg->self.addOption("WindowMinY", m_fWindowMinY); +	cfg->self.addOption("WindowMaxY", m_fWindowMaxY); +	cfg->self.addOption("WindowMinZ", m_fWindowMinZ); +	cfg->self.addOption("WindowMaxZ", m_fWindowMaxZ);  	return cfg;  } diff --git a/src/XMLDocument.cpp b/src/XMLDocument.cpp index 406564f..716ed9e 100644 --- a/src/XMLDocument.cpp +++ b/src/XMLDocument.cpp @@ -32,13 +32,8 @@ $Id$  #include <iostream>  #include <sstream> -#ifdef _MSC_VER  #include "rapidxml/rapidxml.hpp"  #include "rapidxml/rapidxml_print.hpp" -#else -#include "rapidxml.hpp" -#include "rapidxml_print.hpp" -#endif  using namespace rapidxml;  using namespace astra; @@ -94,10 +89,9 @@ XMLDocument* XMLDocument::createDocument(string sRootName)  }  //----------------------------------------------------------------------------- -XMLNode* XMLDocument::getRootNode()  +XMLNode XMLDocument::getRootNode()   { -	// TODO: clean up: this 'new' requires callers to do memory management -	return new XMLNode(fDOMDocument->first_node()); +	return XMLNode(fDOMDocument->first_node());  }  //----------------------------------------------------------------------------- diff --git a/src/XMLNode.cpp b/src/XMLNode.cpp index 4b2bdf4..0ec701f 100644 --- a/src/XMLNode.cpp +++ b/src/XMLNode.cpp @@ -28,15 +28,15 @@ $Id$  #include "astra/XMLNode.h" -#ifdef _MSC_VER  #include "rapidxml/rapidxml.hpp"  #include "rapidxml/rapidxml_print.hpp" -#else -#include "rapidxml.hpp" -#include "rapidxml_print.hpp" -#endif  #include <boost/lexical_cast.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/classification.hpp> + +  using namespace rapidxml;  using namespace astra; @@ -44,21 +44,10 @@ using namespace std;  //----------------------------------------------------------------------------- -// Utility function to delete a list of nodes -static void deleteNodes(list<XMLNode*>& nodes) -{ -	for (list<XMLNode*>::iterator i = nodes.begin(); i != nodes.end(); ++i) -		delete (*i); - -	nodes.clear(); -} - - -//-----------------------------------------------------------------------------  // default constructor  XMLNode::XMLNode()   { - +	fDOMElement = 0;  }  //-----------------------------------------------------------------------------	 @@ -84,14 +73,14 @@ void XMLNode::setDOMNode(xml_node<>* n)  //-----------------------------------------------------------------------------	  // print XML Node -void XMLNode::print() +void XMLNode::print() const  {  	std::cout << fDOMElement;  }  //-----------------------------------------------------------------------------	  // print XML Node -std::string XMLNode::toString() +std::string XMLNode::toString() const  {  	std::string s;  	::print(std::back_inserter(s), *fDOMElement, 0); @@ -100,64 +89,61 @@ std::string XMLNode::toString()  //-----------------------------------------------------------------------------	  // Get single node -XMLNode* XMLNode::getSingleNode(string name)  +XMLNode XMLNode::getSingleNode(string name) const  {  	xml_node<> *node = fDOMElement->first_node(name.c_str()); -	if (node) -		return new XMLNode(node); -	else -		return 0; +	return XMLNode(node);  }  //-----------------------------------------------------------------------------	  // Get list of nodes -list<XMLNode*> XMLNode::getNodes(string name)  +list<XMLNode> XMLNode::getNodes(string name) const  {	 -	list<XMLNode*> result; +	list<XMLNode> result;  	xml_node<> *iter;  	for (iter = fDOMElement->first_node(name.c_str()); iter; iter = iter->next_sibling(name.c_str())) { -		result.push_back(new XMLNode(iter)); +		result.push_back(XMLNode(iter));  	}  	return result;  }  //-----------------------------------------------------------------------------	  // Get list of nodes -list<XMLNode*> XMLNode::getNodes()  +list<XMLNode> XMLNode::getNodes() const  {	 -	list<XMLNode*> result; +	list<XMLNode> result;  	xml_node<> *iter;  	for (iter = fDOMElement->first_node(); iter; iter = iter->next_sibling()) { -		result.push_back(new XMLNode(iter)); +		result.push_back(XMLNode(iter));  	}  	return result;  }  //-----------------------------------------------------------------------------	  // Get name of this node -std::string XMLNode::getName() +std::string XMLNode::getName() const  {  	return fDOMElement->name();  }  //-----------------------------------------------------------------------------	  // Get node content - STRING -string XMLNode::getContent()  +string XMLNode::getContent() const  {  	return fDOMElement->value();  }  //-----------------------------------------------------------------------------	  // Get node content - NUMERICAL -float32 XMLNode::getContentNumerical()  +float32 XMLNode::getContentNumerical() const  {  	return boost::lexical_cast<float32>(getContent());  }  //-----------------------------------------------------------------------------	  // Get node content - BOOLEAN -bool XMLNode::getContentBool()  +bool XMLNode::getContentBool() const  {  	string res = getContent();  	return ((res == "1") || (res == "yes") || (res == "true") || (res == "on")); @@ -165,21 +151,20 @@ bool XMLNode::getContentBool()  //-----------------------------------------------------------------------------	  // Get node content - STRING LIST -vector<string> XMLNode::getContentArray() +vector<string> XMLNode::getContentArray() const  {  	// get listsize  	int iSize = boost::lexical_cast<int>(getAttribute("listsize"));  	// create result array  	vector<string> res(iSize);  	// loop all list item nodes -	list<XMLNode*> nodes = getNodes("ListItem"); -	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) { -		int iIndex = (*it)->getAttributeNumerical("index"); -		string sValue = (*it)->getAttribute("value"); +	list<XMLNode> nodes = getNodes("ListItem"); +	for (list<XMLNode>::iterator it = nodes.begin(); it != nodes.end(); it++) { +		int iIndex = it->getAttributeNumerical("index"); +		string sValue = it->getAttribute("value");  		ASTRA_ASSERT(iIndex < iSize);  		res[iIndex] = sValue;  	} -	deleteNodes(nodes);  	// return   	return res; @@ -187,85 +172,48 @@ vector<string> XMLNode::getContentArray()  //-----------------------------------------------------------------------------	  // Get node content - NUMERICAL LIST -vector<float32> XMLNode::getContentNumericalArray() +// NB: A 2D matrix is returned as a linear list +vector<float32> XMLNode::getContentNumericalArray() const  { -	// is scalar -	if (!hasAttribute("listsize")) { -		vector<float32> res(1); -		res[0] = getContentNumerical(); -		return res; -	} +	string input = getContent(); -	int iSize = boost::lexical_cast<int>(getAttribute("listsize")); -	// create result array -	vector<float32> res(iSize); -	// loop all list item nodes -	list<XMLNode*> nodes = getNodes("ListItem"); -	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) { -		int iIndex = (*it)->getAttributeNumerical("index"); -		float32 fValue = (*it)->getAttributeNumerical("value"); -		ASTRA_ASSERT(iIndex < iSize); -		res[iIndex] = fValue; -	} -	deleteNodes(nodes); -	// return  -	return res; -} +	// split +	std::vector<std::string> items; +	boost::split(items, input, boost::is_any_of(",;")); -vector<double> XMLNode::getContentNumericalArrayDouble() -{ -	// is scalar -	if (!hasAttribute("listsize")) { -		vector<double> res(1); -		res[0] = getContentNumerical(); -		return res; -	} +	// init list +	vector<float32> out; +	out.resize(items.size()); -	int iSize = boost::lexical_cast<int>(getAttribute("listsize")); -	// create result array -	vector<double> res(iSize); -	// loop all list item nodes -	list<XMLNode*> nodes = getNodes("ListItem"); -	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) { -		int iIndex = (*it)->getAttributeNumerical("index"); -		double fValue = (*it)->getAttributeNumericalDouble("value"); -		ASTRA_ASSERT(iIndex < iSize); -		res[iIndex] = fValue; +	// loop elements +	for (unsigned int i = 0; i < items.size(); i++) { +		out[i] = boost::lexical_cast<float32>(items[i]);  	} -	deleteNodes(nodes); -	// return  -	return res; +	return out;  } -//-----------------------------------------------------------------------------	 -// Get node content - NUMERICAL LIST 2 -void XMLNode::getContentNumericalArray(float32*& _pfData, int& _iSize) +vector<double> XMLNode::getContentNumericalArrayDouble() const  { -	// is scalar -	if (!hasAttribute("listsize")) { -		_iSize = 1; -		_pfData = new float32[_iSize]; -		_pfData[0] = getContentNumerical(); -		return; -	} -	// get listsize -	_iSize = boost::lexical_cast<int>(getAttribute("listsize")); -	// create result array -	_pfData = new float32[_iSize]; -	// loop all list item nodes -	list<XMLNode*> nodes = getNodes("ListItem"); -	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) { -		int iIndex = (*it)->getAttributeNumerical("index"); -		float32 fValue = (*it)->getAttributeNumerical("value"); -		ASTRA_ASSERT(iIndex < _iSize); -		_pfData[iIndex] = fValue; +	string input = getContent(); + +	// split +	std::vector<std::string> items; +	boost::split(items, input, boost::is_any_of(",;")); + +	// init list +	vector<double> out; +	out.resize(items.size()); + +	// loop elements +	for (unsigned int i = 0; i < items.size(); i++) { +		out[i] = boost::lexical_cast<double>(items[i]);  	} -	deleteNodes(nodes); +	return out;  }  //-----------------------------------------------------------------------------	  // Is attribute? -bool XMLNode::hasAttribute(string _sName) +bool XMLNode::hasAttribute(string _sName) const  {  	xml_attribute<> *attr = fDOMElement->first_attribute(_sName.c_str());  	return (attr != 0); @@ -273,7 +221,7 @@ bool XMLNode::hasAttribute(string _sName)  //-----------------------------------------------------------------------------	  // Get attribute - STRING -string XMLNode::getAttribute(string _sName, string _sDefaultValue) +string XMLNode::getAttribute(string _sName, string _sDefaultValue) const  {  	xml_attribute<> *attr = fDOMElement->first_attribute(_sName.c_str()); @@ -284,12 +232,12 @@ string XMLNode::getAttribute(string _sName, string _sDefaultValue)  //-----------------------------------------------------------------------------	  // Get attribute - NUMERICAL -float32 XMLNode::getAttributeNumerical(string _sName, float32 _fDefaultValue) +float32 XMLNode::getAttributeNumerical(string _sName, float32 _fDefaultValue) const  {  	if (!hasAttribute(_sName)) return _fDefaultValue;  	return boost::lexical_cast<float32>(getAttribute(_sName));  } -double XMLNode::getAttributeNumericalDouble(string _sName, double _fDefaultValue) +double XMLNode::getAttributeNumericalDouble(string _sName, double _fDefaultValue) const  {  	if (!hasAttribute(_sName)) return _fDefaultValue;  	return boost::lexical_cast<double>(getAttribute(_sName)); @@ -297,7 +245,7 @@ double XMLNode::getAttributeNumericalDouble(string _sName, double _fDefaultValue  //-----------------------------------------------------------------------------	  // Get attribute - BOOLEAN -bool XMLNode::getAttributeBool(string _sName, bool _bDefaultValue) +bool XMLNode::getAttributeBool(string _sName, bool _bDefaultValue) const  {  	if (!hasAttribute(_sName)) return _bDefaultValue;  	string res = getAttribute(_sName); @@ -306,7 +254,7 @@ bool XMLNode::getAttributeBool(string _sName, bool _bDefaultValue)  //-----------------------------------------------------------------------------	  // Has option? -bool XMLNode::hasOption(string _sKey)  +bool XMLNode::hasOption(string _sKey) const  {  	xml_node<> *iter;  	for (iter = fDOMElement->first_node("Option"); iter; iter = iter->next_sibling("Option")) { @@ -319,7 +267,7 @@ bool XMLNode::hasOption(string _sKey)  //-----------------------------------------------------------------------------	  // Get option - STRING -string XMLNode::getOption(string _sKey, string _sDefaultValue)  +string XMLNode::getOption(string _sKey, string _sDefaultValue) const  {  	xml_node<> *iter;  	for (iter = fDOMElement->first_node("Option"); iter; iter = iter->next_sibling("Option")) { @@ -336,7 +284,7 @@ string XMLNode::getOption(string _sKey, string _sDefaultValue)  //-----------------------------------------------------------------------------	  // Get option - NUMERICAL -float32 XMLNode::getOptionNumerical(string _sKey, float32 _fDefaultValue)  +float32 XMLNode::getOptionNumerical(string _sKey, float32 _fDefaultValue) const  {  	if (!hasOption(_sKey)) return _fDefaultValue;  	return boost::lexical_cast<float32>(getOption(_sKey)); @@ -344,7 +292,7 @@ float32 XMLNode::getOptionNumerical(string _sKey, float32 _fDefaultValue)  //-----------------------------------------------------------------------------	  // Get option - BOOL -bool XMLNode::getOptionBool(string _sKey, bool _bDefaultValue) +bool XMLNode::getOptionBool(string _sKey, bool _bDefaultValue) const  {  	bool bHasOption = hasOption(_sKey);  	if (!bHasOption) return _bDefaultValue; @@ -354,20 +302,18 @@ bool XMLNode::getOptionBool(string _sKey, bool _bDefaultValue)  //-----------------------------------------------------------------------------	  // Get option - NUMERICAL ARRAY -vector<float32> XMLNode::getOptionNumericalArray(string _sKey) +vector<float32> XMLNode::getOptionNumericalArray(string _sKey) const  {  	if (!hasOption(_sKey)) return vector<float32>(); -	list<XMLNode*> nodes = getNodes("Option"); -	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) { -		if ((*it)->getAttribute("key") == _sKey) { -			vector<float32> vals = (*it)->getContentNumericalArray(); -			deleteNodes(nodes); +	list<XMLNode> nodes = getNodes("Option"); +	for (list<XMLNode>::iterator it = nodes.begin(); it != nodes.end(); it++) { +		if (it->getAttribute("key") == _sKey) { +			vector<float32> vals = it->getContentNumericalArray();  			return vals;  		}  	} -	deleteNodes(nodes);  	return vector<float32>();  } @@ -390,41 +336,40 @@ vector<float32> XMLNode::getOptionNumericalArray(string _sKey)  //-----------------------------------------------------------------------------  // Add child node - EMPTY -XMLNode* XMLNode::addChildNode(string _sNodeName)  +XMLNode XMLNode::addChildNode(string _sNodeName)   {  	xml_document<> *doc = fDOMElement->document();  	char *node_name = doc->allocate_string(_sNodeName.c_str());  	xml_node<> *node = doc->allocate_node(node_element, node_name);  	fDOMElement->append_node(node); -	// TODO: clean up: this 'new' requires callers to do memory management -	return new XMLNode(node); +	return XMLNode(node);  }  //-----------------------------------------------------------------------------  // Add child node - STRING -XMLNode* XMLNode::addChildNode(string _sNodeName, string _sText)  +XMLNode XMLNode::addChildNode(string _sNodeName, string _sText)   { -	XMLNode* res = addChildNode(_sNodeName); -	res->setContent(_sText); +	XMLNode res = addChildNode(_sNodeName); +	res.setContent(_sText);  	return res;  }  //-----------------------------------------------------------------------------  // Add child node - FLOAT -XMLNode* XMLNode::addChildNode(string _sNodeName, float32 _fValue)  +XMLNode XMLNode::addChildNode(string _sNodeName, float32 _fValue)   { -	XMLNode* res = addChildNode(_sNodeName); -	res->setContent(_fValue); +	XMLNode res = addChildNode(_sNodeName); +	res.setContent(_fValue);  	return res;  }  //-----------------------------------------------------------------------------  // Add child node - LIST -XMLNode* XMLNode::addChildNode(string _sNodeName, float32* _pfList, int _iSize)  +XMLNode XMLNode::addChildNode(string _sNodeName, float32* _pfList, int _iSize)   { -	XMLNode* res = addChildNode(_sNodeName); -	res->setContent(_pfList, _iSize); +	XMLNode res = addChildNode(_sNodeName); +	res.setContent(_pfList, _iSize);  	return res;  } @@ -446,15 +391,68 @@ void XMLNode::setContent(float32 _fValue)  //-----------------------------------------------------------------------------	  // Set content - LIST -void XMLNode::setContent(float32* pfList, int _iSize)  -{ + +template<typename T> +static std::string setContentList_internal(T* pfList, int _iSize) {  	std::string str = (_iSize > 0) ? boost::lexical_cast<std::string>(pfList[0]) : "";  	for (int i = 1; i < _iSize; i++) {  		str += "," + boost::lexical_cast<std::string>(pfList[i]);  	} -	setContent(str); +	return str; +} + +void XMLNode::setContent(float32* pfList, int _iSize) +{ +	setContent(setContentList_internal<float32>(pfList, _iSize)); +} + +void XMLNode::setContent(double* pfList, int _iSize) +{ +	setContent(setContentList_internal<double>(pfList, _iSize)); +} + +//-----------------------------------------------------------------------------	 +// Set content - MATRIX + +template<typename T> +static std::string setContentMatrix_internal(T* _pfMatrix, int _iWidth, int _iHeight, bool transposed) +{ +	std::string str = ""; + +	int s1,s2; + +	if (!transposed) { +		s1 = 1; +		s2 = _iWidth; +	} else { +		s1 = _iHeight; +		s2 = 1; +	} + +	for (int y = 0; y < _iHeight; ++y) { +		if (_iWidth > 0) +			str += boost::lexical_cast<std::string>(_pfMatrix[0*s1 + y*s2]); +			for (int x = 1; x < _iWidth; x++) +				str += "," + boost::lexical_cast<std::string>(_pfMatrix[x*s1 + y*s2]); + +		if (y != _iHeight-1) +			str += ";"; +	} + +	return str;  } +void XMLNode::setContent(float32* _pfMatrix, int _iWidth, int _iHeight, bool transposed) +{ +	setContent(setContentMatrix_internal<float32>(_pfMatrix, _iWidth, _iHeight, transposed)); +} + +void XMLNode::setContent(double* _pfMatrix, int _iWidth, int _iHeight, bool transposed) +{ +	setContent(setContentMatrix_internal<double>(_pfMatrix, _iWidth, _iHeight, transposed)); +} + +  //-----------------------------------------------------------------------------	  // Add attribute - STRING  void XMLNode::addAttribute(string _sName, string _sText)  @@ -477,20 +475,18 @@ void XMLNode::addAttribute(string _sName, float32 _fValue)  // Add option - STRING  void XMLNode::addOption(string _sName, string _sText)   { -	XMLNode* node = addChildNode("Option"); -	node->addAttribute("key", _sName); -	node->addAttribute("value", _sText); -	delete node; +	XMLNode node = addChildNode("Option"); +	node.addAttribute("key", _sName); +	node.addAttribute("value", _sText);  }  //-----------------------------------------------------------------------------	  // Add option - FLOAT  void XMLNode::addOption(string _sName, float32 _sText)   { -	XMLNode* node = addChildNode("Option"); -	node->addAttribute("key", _sName); -	node->addAttribute("value", _sText); -	delete node; +	XMLNode node = addChildNode("Option"); +	node.addAttribute("key", _sName); +	node.addAttribute("value", _sText);  }  //-----------------------------------------------------------------------------	 diff --git a/tests/test_Fourier.cpp b/tests/test_Fourier.cpp index 2602edb..ef12747 100644 --- a/tests/test_Fourier.cpp +++ b/tests/test_Fourier.cpp @@ -105,8 +105,8 @@ BOOST_AUTO_TEST_CASE( testFourier_FFT_1D_1 )  {  	astra::float32 inR[8] = { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f };  	astra::float32 inI[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; -	astra::float32 outR[5]; -	astra::float32 outI[5]; +	astra::float32 outR[8]; +	astra::float32 outI[8];  	astra::fastTwoPowerFourierTransform1D(8, inR, inI, outR, outI, 1, 1, false); diff --git a/tests/test_ParallelBeamLineKernelProjector2D.cpp b/tests/test_ParallelBeamLineKernelProjector2D.cpp index 86bc54f..c56ff37 100644 --- a/tests/test_ParallelBeamLineKernelProjector2D.cpp +++ b/tests/test_ParallelBeamLineKernelProjector2D.cpp @@ -77,6 +77,8 @@ BOOST_FIXTURE_TEST_CASE( testParallelBeamLineKernelProjector2D_Rectangle, TestPa  		fWeight += pPix[i].m_fWeight;  	BOOST_CHECK_SMALL(fWeight - 7.13037f, 0.00001f); + +	delete[] pPix;  } diff --git a/tests/test_XMLDocument.cpp b/tests/test_XMLDocument.cpp index adabdd6..95429cb 100644 --- a/tests/test_XMLDocument.cpp +++ b/tests/test_XMLDocument.cpp @@ -32,18 +32,22 @@ $Id$  #include <boost/test/auto_unit_test.hpp>  #include "astra/XMLDocument.h" +#include "astra/Config.h"  BOOST_AUTO_TEST_CASE( testXMLDocument_Constructor1 )  {  	astra::XMLDocument *doc = astra::XMLDocument::createDocument("test");  	BOOST_REQUIRE(doc); -	astra::XMLNode *root = doc->getRootNode(); +	astra::XMLNode root = doc->getRootNode();  	BOOST_REQUIRE(root); -	BOOST_CHECK(root->getName() == "test"); -	BOOST_CHECK(root->getContent().empty()); +	BOOST_CHECK(root.getName() == "test"); +	BOOST_CHECK(root.getContent().empty()); + +	delete doc; +  }  BOOST_AUTO_TEST_CASE( testXMLDocument_FileIO ) @@ -53,12 +57,15 @@ BOOST_AUTO_TEST_CASE( testXMLDocument_FileIO )  	doc->saveToFile("test.xml");  	astra::XMLDocument *doc2 = astra::XMLDocument::readFromFile("test.xml"); -	astra::XMLNode *root = doc2->getRootNode(); +	astra::XMLNode root = doc2->getRootNode();  	BOOST_REQUIRE(root); -	BOOST_CHECK(root->getName() == "test"); -	BOOST_CHECK(root->getContent().empty()); +	BOOST_CHECK(root.getName() == "test"); +	BOOST_CHECK(root.getContent().empty()); + +	delete doc2; +	delete doc;  } @@ -67,32 +74,28 @@ BOOST_AUTO_TEST_CASE( testXMLDocument_CreateNodes )  	astra::XMLDocument *doc = astra::XMLDocument::createDocument("test");  	BOOST_REQUIRE(doc); -	astra::XMLNode *root = doc->getRootNode(); +	astra::XMLNode root = doc->getRootNode();  	BOOST_REQUIRE(root); -	astra::XMLNode *node = root->addChildNode("child"); +	astra::XMLNode node = root.addChildNode("child");  	BOOST_REQUIRE(node); -	node->addAttribute("attr", "val"); +	node.addAttribute("attr", "val");  	doc->saveToFile("test2.xml"); -	delete node; -	delete root;  	delete doc;  	doc = astra::XMLDocument::readFromFile("test2.xml");  	BOOST_REQUIRE(doc);  	root = doc->getRootNode();  	BOOST_REQUIRE(node); -	node = root->getSingleNode("child"); +	node = root.getSingleNode("child");  	BOOST_REQUIRE(node); -	BOOST_CHECK(node->hasAttribute("attr")); -	BOOST_CHECK(node->getAttribute("attr") == "val"); +	BOOST_CHECK(node.hasAttribute("attr")); +	BOOST_CHECK(node.getAttribute("attr") == "val"); -	delete node; -	delete root;  	delete doc;  } @@ -101,16 +104,18 @@ BOOST_AUTO_TEST_CASE( testXMLDocument_Options )  	astra::XMLDocument *doc = astra::XMLDocument::createDocument("test");  	BOOST_REQUIRE(doc); -	astra::XMLNode *root = doc->getRootNode(); +	astra::XMLNode root = doc->getRootNode();  	BOOST_REQUIRE(root); -	BOOST_CHECK(!root->hasOption("opt")); +	BOOST_CHECK(!root.hasOption("opt")); + +	root.addOption("opt", "val"); -	root->addOption("opt", "val"); +	BOOST_CHECK(root.hasOption("opt")); -	BOOST_CHECK(root->hasOption("opt")); +	BOOST_CHECK(root.getOption("opt") == "val"); -	BOOST_CHECK(root->getOption("opt") == "val"); +	delete doc;  } @@ -119,40 +124,51 @@ BOOST_AUTO_TEST_CASE( testXMLDocument_List )  	astra::XMLDocument *doc = astra::XMLDocument::createDocument("test");  	BOOST_REQUIRE(doc); -	astra::XMLNode *root = doc->getRootNode(); +	astra::XMLNode root = doc->getRootNode();  	BOOST_REQUIRE(root); -	astra::XMLNode *node = root->addChildNode("child"); +	astra::XMLNode node = root.addChildNode("child");  	BOOST_REQUIRE(node);  	float fl[] = { 1.0, 3.5, 2.0, 4.75 }; -	node->setContent(fl, sizeof(fl)/sizeof(fl[0])); +	node.setContent(fl, sizeof(fl)/sizeof(fl[0]));  	doc->saveToFile("test3.xml"); -	delete node; -	delete root;  	delete doc;  	doc = astra::XMLDocument::readFromFile("test3.xml");  	BOOST_REQUIRE(doc);  	root = doc->getRootNode();  	BOOST_REQUIRE(root); -	node = root->getSingleNode("child"); +	node = root.getSingleNode("child");  	BOOST_REQUIRE(node); -	std::vector<astra::float32> f = node->getContentNumericalArray(); +	std::vector<astra::float32> f = node.getContentNumericalArray();  	BOOST_CHECK(f[0] == fl[0]);  	BOOST_CHECK(f[1] == fl[1]);  	BOOST_CHECK(f[2] == fl[2]);  	BOOST_CHECK(f[3] == fl[3]); -	delete node; -	delete root;  	delete doc;  } +BOOST_AUTO_TEST_CASE( testXMLDocument_Config ) +{ +	astra::Config* cfg = new astra::Config(); +	cfg->initialize("VolumeGeometry2D"); + +	cfg->self.addChildNode("GridColCount", 1); +	cfg->self.addChildNode("GridRowCount", 2); + +	cfg->self.addOption("WindowMinX", 3); +	cfg->self.addOption("WindowMaxX", 4); +	cfg->self.addOption("WindowMinY", 5); +	cfg->self.addOption("WindowMaxY", 6); + +	delete cfg; +} | 
