summaryrefslogtreecommitdiffstats
path: root/matlab
diff options
context:
space:
mode:
authorWillem Jan Palenstijn <WillemJan.Palenstijn@uantwerpen.be>2013-07-01 22:34:11 +0000
committerwpalenst <WillemJan.Palenstijn@uantwerpen.be>2013-07-01 22:34:11 +0000
commitb2fc6c70434674d74551c3a6c01ffb3233499312 (patch)
treeb17f080ebc504ab85ebb7c3d89f917fd87ce9e00 /matlab
downloadastra-b2fc6c70434674d74551c3a6c01ffb3233499312.tar.gz
astra-b2fc6c70434674d74551c3a6c01ffb3233499312.tar.bz2
astra-b2fc6c70434674d74551c3a6c01ffb3233499312.tar.xz
astra-b2fc6c70434674d74551c3a6c01ffb3233499312.zip
Update version to 1.3
Diffstat (limited to 'matlab')
-rw-r--r--matlab/algorithms/DART/DARTalgorithm.m229
-rw-r--r--matlab/algorithms/DART/IterativeTomography.m455
-rw-r--r--matlab/algorithms/DART/IterativeTomography3D.m433
-rw-r--r--matlab/algorithms/DART/Kernels.m68
-rw-r--r--matlab/algorithms/DART/MaskingDefault.m212
-rw-r--r--matlab/algorithms/DART/MaskingGPU.m94
-rw-r--r--matlab/algorithms/DART/OutputDefault.m173
-rw-r--r--matlab/algorithms/DART/SegmentationDefault.m55
-rw-r--r--matlab/algorithms/DART/SmoothingDefault.m179
-rw-r--r--matlab/algorithms/DART/SmoothingGPU.m119
-rw-r--r--matlab/algorithms/DART/StatisticsDefault.m72
-rw-r--r--matlab/algorithms/DART/TomographyDefault.m73
-rw-r--r--matlab/algorithms/DART/TomographyDefault3D.m73
-rw-r--r--matlab/algorithms/DART/examples/cylinders.pngbin0 -> 3934 bytes
-rw-r--r--matlab/algorithms/DART/examples/example1.m79
-rw-r--r--matlab/algorithms/DART/examples/example2.m80
-rw-r--r--matlab/algorithms/DART/examples/example3.m79
-rw-r--r--matlab/algorithms/DART/examples/phantom3d.matbin0 -> 242654 bytes
-rw-r--r--matlab/mex/astra_mex.cpp121
-rw-r--r--matlab/mex/astra_mex_algorithm_c.cpp348
-rw-r--r--matlab/mex/astra_mex_algorithm_vc08.vcproj593
-rw-r--r--matlab/mex/astra_mex_c.cpp127
-rw-r--r--matlab/mex/astra_mex_data2d_c.cpp667
-rw-r--r--matlab/mex/astra_mex_data2d_vc08.vcproj591
-rw-r--r--matlab/mex/astra_mex_data3d_c.cpp1036
-rw-r--r--matlab/mex/astra_mex_data3d_vc08.vcproj588
-rw-r--r--matlab/mex/astra_mex_matrix_c.cpp437
-rw-r--r--matlab/mex/astra_mex_matrix_vc08.vcproj591
-rw-r--r--matlab/mex/astra_mex_projector3d_c.cpp433
-rw-r--r--matlab/mex/astra_mex_projector3d_vc08.vcproj588
-rw-r--r--matlab/mex/astra_mex_projector_c.cpp510
-rw-r--r--matlab/mex/astra_mex_projector_vc08.vcproj591
-rw-r--r--matlab/mex/astra_mex_vc08.vcproj591
-rw-r--r--matlab/mex/mex.def1
-rw-r--r--matlab/mex/mexHelpFunctions.cpp642
-rw-r--r--matlab/mex/mexHelpFunctions.h76
-rw-r--r--matlab/tools/ROIselectfull.m18
-rw-r--r--matlab/tools/astra_add_noise_to_sino.m47
-rw-r--r--matlab/tools/astra_clear.m19
-rw-r--r--matlab/tools/astra_create_backprojection.m63
-rw-r--r--matlab/tools/astra_create_backprojection3d_cuda.m54
-rw-r--r--matlab/tools/astra_create_backprojection_cuda.m39
-rw-r--r--matlab/tools/astra_create_fbp_reconstruction.m23
-rw-r--r--matlab/tools/astra_create_proj_geom.m204
-rw-r--r--matlab/tools/astra_create_projector.m50
-rw-r--r--matlab/tools/astra_create_reconstruction.m97
-rw-r--r--matlab/tools/astra_create_reconstruction_cuda.m80
-rw-r--r--matlab/tools/astra_create_sino.m63
-rw-r--r--matlab/tools/astra_create_sino3d_cuda.m54
-rw-r--r--matlab/tools/astra_create_sino_cuda.m58
-rw-r--r--matlab/tools/astra_create_sino_gpu.m58
-rw-r--r--matlab/tools/astra_create_sino_sampling.m59
-rw-r--r--matlab/tools/astra_create_vol_geom.m96
-rw-r--r--matlab/tools/astra_data_gui.figbin0 -> 5810 bytes
-rw-r--r--matlab/tools/astra_data_gui.m396
-rw-r--r--matlab/tools/astra_data_op.m11
-rw-r--r--matlab/tools/astra_data_op_mask.m12
-rw-r--r--matlab/tools/astra_downsample_sinogram.m36
-rw-r--r--matlab/tools/astra_geom_2vec.m84
-rw-r--r--matlab/tools/astra_geom_postalignment.m11
-rw-r--r--matlab/tools/astra_geom_size.m28
-rw-r--r--matlab/tools/astra_geom_superresolution.m14
-rw-r--r--matlab/tools/astra_imshow.m10
-rw-r--r--matlab/tools/astra_mex.m24
-rw-r--r--matlab/tools/astra_mex_algorithm.m24
-rw-r--r--matlab/tools/astra_mex_data2d.m24
-rw-r--r--matlab/tools/astra_mex_data3d.m24
-rw-r--r--matlab/tools/astra_mex_matrix.m24
-rw-r--r--matlab/tools/astra_mex_projector.m24
-rw-r--r--matlab/tools/astra_mex_projector3d.m24
-rw-r--r--matlab/tools/astra_projector_handle.m29
-rw-r--r--matlab/tools/astra_set_directory.m27
-rw-r--r--matlab/tools/astra_struct.m37
-rw-r--r--matlab/tools/compute_rnmp.m29
-rw-r--r--matlab/tools/createOrderART.m66
-rw-r--r--matlab/tools/downsample_sinogram.m12
-rw-r--r--matlab/tools/imreadgs.m26
-rw-r--r--matlab/tools/imresize3D.m26
-rw-r--r--matlab/tools/imscale.m28
-rw-r--r--matlab/tools/imwritesc.m22
-rw-r--r--matlab/tools/kaiserBessel.m31
-rw-r--r--matlab/tools/linspace2.m25
-rw-r--r--matlab/tools/overlayImage.m24
-rw-r--r--matlab/tools/rebin_fan2par.m82
-rw-r--r--matlab/tools/sliceExtractor.m34
85 files changed, 13354 insertions, 0 deletions
diff --git a/matlab/algorithms/DART/DARTalgorithm.m b/matlab/algorithms/DART/DARTalgorithm.m
new file mode 100644
index 0000000..b7e63b5
--- /dev/null
+++ b/matlab/algorithms/DART/DARTalgorithm.m
@@ -0,0 +1,229 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef DARTalgorithm < matlab.mixin.Copyable
+
+ % Algorithm class for Discrete Algebraic Reconstruction Technique (DART).
+
+ % todo: reset()
+ % todo: fixed random seed
+ % todo: initialize from settings (?)
+
+ %----------------------------------------------------------------------
+ properties (GetAccess=public, SetAccess=public)
+
+ tomography = TomographyDefault(); % POLICY: Tomography object.
+ segmentation = SegmentationDefault(); % POLICY: Segmentation object.
+ smoothing = SmoothingDefault(); % POLICY: Smoothing object.
+ masking = MaskingDefault(); % POLICY: Masking object.
+ output = OutputDefault(); % POLICY: Output object.
+ statistics = StatisticsDefault(); % POLICY: Statistics object.
+
+ base = struct(); % DATA(set): base structure, should contain: 'sinogram', 'proj_geom', 'phantom' (optional).
+
+ memory = 'yes'; % SETTING: reduce memory usage? (disables some features)
+
+ testdata = struct();
+
+ end
+ %----------------------------------------------------------------------
+ properties (GetAccess=public, SetAccess=private)
+ V0 = []; % DATA(get): Initial reconstruction.
+ V = []; % DATA(get): Reconstruction.
+ S = []; % DATA(get): Segmentation.
+ R = []; % DATA(get): Residual projection data.
+ Mask = []; % DATA(get): Reconstruction Mask.
+ stats = struct(); % Structure containing various statistics.
+ iterationcount = 0; % Number of performed iterations.
+ start_tic = 0;
+ initialized = 0; % Is initialized?
+ end
+ %----------------------------------------------------------------------
+ properties (Access=private)
+ adaptparam_name = {};
+ adaptparam_values = {};
+ adaptparam_iters = {};
+ end
+
+ %----------------------------------------------------------------------
+ methods
+
+ %------------------------------------------------------------------
+ function this = DARTalgorithm(base)
+ % Constructor
+ % >> D = DARTalgorithm(base); base is a matlab struct (or the path towards one)
+ % that should contain 'sinogram', 'proj_geom'.
+
+ if ischar(base)
+ this.base = load(base);
+ else
+ this.base = base;
+ end
+ end
+
+
+ %------------------------------------------------------------------
+ function D = deepcopy(this)
+ % Create a deep copy of this object.
+ % >> D2 = D.deepcopy();
+
+ D = copy(this);
+ props = properties(this);
+ for i = 1:length(props)
+ if isa(this.(props{i}), 'handle')
+ D.(props{i}) = copy(this.(props{i}));
+ end
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ function this = initialize(this)
+ % Initializes this object.
+ % >> D.initialize();
+
+ % Initialize tomography part
+ this.tomography.initialize(this);
+
+ % Create an Initial Reconstruction
+ if isfield(this.base, 'V0')
+ this.V0 = this.base.V0;
+ else
+ this.output.pre_initial_iteration(this);
+ this.V0 = this.tomography.createInitialReconstruction(this, this.base.sinogram);
+ this.output.post_initial_iteration(this);
+ end
+ this.V = this.V0;
+ if strcmp(this.memory,'yes')
+ this.base.V0 = [];
+ this.V0 = [];
+ end
+ this.initialized = 1;
+ end
+
+ %------------------------------------------------------------------
+ % iterate
+ function this = iterate(this, iters)
+ % Perform several iterations of the DART algorithm.
+ % >> D.iterate(iterations);
+
+ this.start_tic = tic;
+
+ for iteration = 1:iters
+
+ this.iterationcount = this.iterationcount + 1;
+
+ %----------------------------------------------------------
+ % Initial Output
+ this.output.pre_iteration(this);
+
+ %----------------------------------------------------------
+ % Update Adaptive Parameters
+ for i = 1:numel(this.adaptparam_name)
+
+ for j = 1:numel(this.adaptparam_iters{i})
+ if this.iterationcount == this.adaptparam_iters{i}(j)
+ new_value = this.adaptparam_values{i}(j);
+ eval(['this.' this.adaptparam_name{i} ' = ' num2str(new_value) ';']);
+ disp(['value ' this.adaptparam_name{i} ' changed to ' num2str(new_value) ]);
+ end
+ end
+
+ end
+
+ %----------------------------------------------------------
+ % Segmentation
+ this.segmentation.estimate_grey_levels(this, this.V);
+ this.S = this.segmentation.apply(this, this.V);
+
+ %----------------------------------------------------------
+ % Select Update and Fixed Pixels
+ this.Mask = this.masking.apply(this, this.S);
+
+ this.V = (this.V .* this.Mask) + (this.S .* (1 - this.Mask));
+ %this.V(this.Mask == 0) = this.S(this.Mask == 0);
+
+ F = this.V;
+ F(this.Mask == 1) = 0;
+
+ %----------------------------------------------------------
+ % Create Residual Projection Difference
+ %this.testdata.F{iteration} = F;
+ this.R = this.base.sinogram - this.tomography.createForwardProjection(this, F);
+ %this.testdata.R{iteration} = this.R;
+
+ %----------------------------------------------------------
+ % ART Loose Part
+ %this.testdata.V1{iteration} = this.V;
+ %this.testdata.Mask{iteration} = this.Mask;
+
+ %X = zeros(size(this.V));
+ %Y = this.tomography.createReconstruction(this, this.R, X, this.Mask);
+ %this.V(this.Mask) = Y(this.Mask);
+ this.V = this.tomography.createReconstruction(this, this.R, this.V, this.Mask);
+
+ %this.testdata.V2{iteration} = this.V;
+
+ %----------------------------------------------------------
+ % Blur
+ this.V = this.smoothing.apply(this, this.V);
+ %this.testdata.V3{iteration} = this.V;
+
+ %----------------------------------------------------------
+ % Calculate Statistics
+ this.stats = this.statistics.apply(this);
+
+ %----------------------------------------------------------
+ % Output
+ this.output.post_iteration(this);
+
+ end % end iteration loop
+
+ %test = this.testdata;
+ %save('testdata.mat','test');
+
+ end
+
+ %------------------------------------------------------------------
+ % get data
+ function data = getdata(this, string)
+ if numel(this.(string)) == 1
+ data = astra_mex_data2d('get',this.(string));
+ else
+ data = this.(string);
+ end
+ end
+
+ %------------------------------------------------------------------
+ % add adaptive parameter
+ function this = adaptiveparameter(this, name, values, iterations)
+ this.adaptparam_name{end+1} = name;
+ this.adaptparam_values{end+1} = values;
+ this.adaptparam_iters{end+1} = iterations;
+ end
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = tomography.getsettings();
+
+ settings.tomography = this.tomography.getsettings();
+ settings.smoothing = this.smoothing.getsettings();
+ settings.masking = this.masking.getsettings();
+ settings.segmentation = this.segmentation.getsettings();
+ end
+ %------------------------------------------------------------------
+
+ end % methods
+
+end % class
+
+
diff --git a/matlab/algorithms/DART/IterativeTomography.m b/matlab/algorithms/DART/IterativeTomography.m
new file mode 100644
index 0000000..b30640e
--- /dev/null
+++ b/matlab/algorithms/DART/IterativeTomography.m
@@ -0,0 +1,455 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef IterativeTomography < matlab.mixin.Copyable
+
+ % Algorithm class for 2D Iterative Tomography.
+
+ %----------------------------------------------------------------------
+ properties (SetAccess=public, GetAccess=public)
+ superresolution = 1; % SETTING: Volume upsampling factor.
+ proj_type = 'linear'; % SETTING: Projector type, only when gpu='no'.
+ method = 'SIRT_CUDA'; % SETTING: Iterative method (see ASTRA toolbox documentation).
+ gpu = 'yes'; % SETTING: Use gpu? {'yes', 'no'}
+ gpu_core = 0; % SETTING: Which gpu core to use? Only when gpu='yes'.
+ inner_circle = 'yes'; % SETTING: Do roi only? {'yes', 'no'}
+ image_size = []; % SETTING: Overwrite default reconstruction size. Only if no vol_geom is specified.
+ use_minc = 'no'; % SETTING: Use minimum constraint. {'no', 'yes'}
+ end
+ %----------------------------------------------------------------------
+ properties (SetAccess=public, GetAccess=public)
+ sinogram = []; % DATA: Projection data.
+ proj_geom = []; % DATA: Projection geometry.
+ V = []; % DATA: Volume data. Also used to set initial estimate (optional).
+ vol_geom = []; % DATA: Volume geometry.
+ end
+ %----------------------------------------------------------------------
+ properties (SetAccess=private, GetAccess=public)
+ initialized = 0; % Is this object initialized?
+ end
+ %----------------------------------------------------------------------
+ properties (SetAccess=protected, GetAccess=protected)
+ proj_geom_sr = []; % PROTECTED: geometry of sinogram (with super-resolution)
+ proj_id = []; % PROTECTED: astra id of projector (when gpu='no')
+ proj_id_sr = []; % PROTECTED: astra id of super-resolution projector (when gpu='no')
+ cfg_base = struct(); % PROTECTED: base configuration structure for the reconstruction algorithm.
+ end
+ %----------------------------------------------------------------------
+
+ methods (Access=public)
+
+ %------------------------------------------------------------------
+ function this = IterativeTomography(varargin)
+ % Constructor
+ % >> tomography = IterativeTomography();
+ % >> tomography = IterativeTomography(base); base struct should contain fields 'sinogram' and 'proj_geom'.
+ % >> tomography = IterativeTomography(base_filename); mat-file should contain 'sinogram' and 'proj_geom'.
+ % >> tomography = IterativeTomography(proj_geom, vol_geom);
+ % >> tomography = IterativeTomography(sinogram, proj_geom);
+
+ % Input: IterativeTomography(base)
+ if nargin == 1
+ if ischar(varargin{1})
+ this.sinogram = load(varargin{1},'sinogram');
+ this.proj_geom = load(varargin{1},'proj_geom');
+ else
+ this.sinogram = varargin{1}.sinogram;
+ this.proj_geom = varargin{1}.proj_geom;
+ end
+ end
+ % Input: IterativeTomography(proj_geom, vol_geom)
+ if nargin == 2 && isstruct(varargin{1}) && isstruct(varargin{2})
+ this.proj_geom = varargin{1};
+ this.vol_geom = varargin{2};
+ % Input: IterativeTomography(sinogram, proj_geom)
+ elseif nargin == 2
+ this.sinogram = varargin{1};
+ this.proj_geom = varargin{2};
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ function delete(this)
+ % Destructor
+ % >> clear tomography;
+ if strcmp(this.gpu,'no') && numel(this.proj_id) > 0
+ astra_mex_projector('delete', this.proj_id, this.proj_id_sr);
+ end
+ end
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = tomography.getsettings();
+ settings.superresolution = this.superresolution;
+ settings.proj_type = this.proj_type;
+ settings.method = this.method;
+ settings.gpu = this.gpu;
+ settings.gpu_core = this.gpu_core;
+ settings.inner_circle = this.inner_circle;
+ settings.image_size = this.image_size;
+ settings.use_minc = this.use_minc;
+ end
+
+ %------------------------------------------------------------------
+ function ok = initialize(this)
+ % Initialize this object. Returns 1 if succesful.
+ % >> tomography.initialize();
+
+ % create projection geometry with super-resolution
+ this.proj_geom_sr = astra_geom_superresolution(this.proj_geom, this.superresolution);
+
+ % if no volume geometry is specified by the user: create volume geometry
+ if numel(this.vol_geom) == 0
+ if numel(this.image_size) < 2
+ this.image_size(1) = this.proj_geom.DetectorCount;
+ this.image_size(2) = this.proj_geom.DetectorCount;
+ end
+ this.vol_geom = astra_create_vol_geom(this.image_size(1) * this.superresolution, this.image_size(2) * this.superresolution, ...
+ -this.image_size(1)/2, this.image_size(1)/2, -this.image_size(2)/2, this.image_size(2)/2);
+ else
+ this.image_size(1) = this.vol_geom.GridRowCount;
+ this.image_size(2) = this.vol_geom.GridColCount;
+ end
+
+ % create projector
+ if strcmp(this.gpu, 'no')
+ this.proj_id = astra_create_projector(this.proj_type, this.proj_geom, this.vol_geom);
+ this.proj_id_sr = astra_create_projector(this.proj_type, this.proj_geom_sr, this.vol_geom);
+ end
+
+ % create reconstruction configuration
+ this.cfg_base = astra_struct(upper(this.method));
+ if strcmp(this.gpu,'no')
+ this.cfg_base.ProjectorId = this.proj_id;
+ this.cfg_base.ProjectionGeometry = this.proj_geom;
+ this.cfg_base.ReconstructionGeometry = this.vol_geom;
+ this.cfg_base.option.ProjectionOrder = 'random';
+ end
+ this.cfg_base.option.DetectorSuperSampling = this.superresolution;
+ %this.cfg_base.option.DetectorSuperSampling = 8;
+ if strcmp(this.gpu,'yes')
+ this.cfg_base.option.GPUindex = this.gpu_core;
+ end
+ this.cfg_base.option.UseMinConstraint = this.use_minc;
+
+ this.initialized = 1;
+ ok = this.initialized;
+ end
+
+ %------------------------------------------------------------------
+ function P = project(this, volume)
+ % Compute forward projection.
+ % Stores sinogram in tomography.sinogram if it is still empty.
+ % >> P = tomography.project(); projects 'tomography.V'.
+ % >> P = tomography.project(volume); projects 'volume'.
+
+ if ~this.initialized
+ this.initialize();
+ end
+
+ if nargin == 1 % tomography.project();
+ P = this.project_c(this.V);
+
+ elseif nargin == 2 % tomography.project(volume);
+ P = this.project_c(volume);
+ end
+
+ % store
+ if numel(this.sinogram) == 0
+ this.sinogram = P;
+ end
+ end
+
+ %------------------------------------------------------------------
+ function V = reconstruct(this, iterations)
+ % Compute reconstruction.
+ % Uses tomography.sinogram
+ % Initial solution (if available) should be stored in tomography.V
+ % >> V = tomography.reconstruct(iterations);
+
+ if ~this.initialized
+ this.initialize();
+ end
+
+ this.V = this.reconstruct_c(this.sinogram, this.V, [], iterations);
+ if strcmp(this.inner_circle,'yes')
+ this.V = this.selectROI(this.V);
+ end
+ V = this.V;
+ end
+
+ %------------------------------------------------------------------
+ function I = reconstructMask(this, mask, iterations)
+ % Compute reconstruction with mask.
+ % Uses tomography.sinogram
+ % Initial solution (if available) should be stored in tomography.V
+ % >> V = tomography.reconstructMask(mask, iterations);
+
+ if ~this.initialized
+ this.initialize();
+ end
+
+ if strcmp(this.inner_circle,'yes')
+ mask = this.selectROI(mask);
+ end
+ I = this.reconstruct_c(this.sinogram, this.V, mask, iterations);
+ end
+ %------------------------------------------------------------------
+
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access = protected)
+
+ %------------------------------------------------------------------
+ % Protected function: create FP
+ function sinogram = project_c(this, volume)
+
+ if this.initialized == 0
+ error('IterativeTomography not initialized');
+ end
+
+ % data is stored in astra memory
+ if numel(volume) == 1
+
+ if strcmp(this.gpu, 'yes')
+ sinogram_tmp = astra_create_sino_cuda(volume, this.proj_geom_sr, this.vol_geom, this.gpu_core);
+ else
+ sinogram_tmp = astra_create_sino(volume, this.proj_id);
+ end
+
+ % sinogram downsampling
+ if this.superresolution > 1
+ sinogram_data = astra_mex_data2d('get', sinogram_tmp);
+ astra_mex_data2d('delete', sinogram_tmp);
+ sinogram_data = downsample_sinogram(sinogram_data, this.superresolution);
+ %if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat')
+ % sinogram = sinogram / this.superresolution;
+ %end
+ sinogram = astra_mex_data2d('create','sino', this.proj_geom, sinogram_data);
+ else
+ sinogram = sinogram_tmp;
+ end
+
+ % data is stored in matlab memory
+ else
+
+ % 2D and 3D slice by slice
+ sinogram_tmp = zeros([astra_geom_size(this.proj_geom_sr), size(volume,3)]);
+ sinogram_tmp2 = zeros([astra_geom_size(this.proj_geom), size(volume,3)]);
+ for slice = 1:size(volume,3)
+
+ if strcmp(this.gpu, 'yes')
+ [tmp_id, sinogram_tmp2(:,:,slice)] = astra_create_sino_sampling(volume(:,:,slice), this.proj_geom, this.vol_geom, this.gpu_core, this.superresolution);
+ astra_mex_data2d('delete', tmp_id);
+ else
+ [tmp_id, tmp] = astra_create_sino(volume(:,:,slice), this.proj_id_sr);
+ sinogram_tmp2(:,:,slice) = downsample_sinogram(tmp, this.superresolution) * (this.superresolution^2);
+ astra_mex_data2d('delete', tmp_id);
+ end
+
+ end
+
+ % sinogram downsampling
+ if strcmp(this.gpu, 'yes')
+ %sinogram = downsample_sinogram(sinogram_tmp, this.superresolution);
+ sinogram2 = sinogram_tmp2;
+ if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat')
+ sinogram2 = sinogram2 / this.superresolution;
+ elseif strcmp(this.proj_geom.type,'parallel')
+ sinogram2 = sinogram2 / (this.superresolution * this.superresolution);
+ end
+ sinogram = sinogram2;
+ else
+ sinogram = sinogram_tmp2;
+ end
+
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ % Protected function: reconstruct
+ function V = reconstruct_c(this, sinogram, V0, mask, iterations)
+
+ if this.initialized == 0
+ error('IterativeTomography not initialized');
+ end
+
+ % data is stored in astra memory
+ if numel(sinogram) == 1
+ V = this.reconstruct_c_astra(sinogram, V0, mask, iterations);
+
+ % data is stored in matlab memory
+ else
+ V = this.reconstruct_c_matlab(sinogram, V0, mask, iterations);
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ % Protected function: reconstruct (data in matlab)
+ function V = reconstruct_c_matlab(this, sinogram, V0, mask, iterations)
+
+ if this.initialized == 0
+ error('IterativeTomography not initialized');
+ end
+
+ % parse method
+ method2 = upper(this.method);
+ if strcmp(method2, 'SART') || strcmp(method2, 'SART_CUDA')
+ iterations = iterations * size(sinogram,1);
+ elseif strcmp(method2, 'ART')
+ iterations = iterations * numel(sinogram);
+ end
+
+ % create data objects
+ V = zeros(this.vol_geom.GridRowCount, this.vol_geom.GridColCount, size(sinogram,3));
+ reconstruction_id = astra_mex_data2d('create', '-vol', this.vol_geom);
+ sinogram_id = astra_mex_data2d('create', '-sino', this.proj_geom);
+ if numel(mask) > 0
+ mask_id = astra_mex_data2d('create', '-vol', this.vol_geom);
+ end
+
+ % algorithm configuration
+ cfg = this.cfg_base;
+ cfg.ProjectionDataId = sinogram_id;
+ cfg.ReconstructionDataId = reconstruction_id;
+ if numel(mask) > 0
+ cfg.option.ReconstructionMaskId = mask_id;
+ end
+ alg_id = astra_mex_algorithm('create', cfg);
+
+ % loop slices
+ for slice = 1:size(sinogram,3)
+
+ % fetch slice of initial reconstruction
+ if numel(V0) > 0
+ astra_mex_data2d('store', reconstruction_id, V0(:,:,slice));
+ else
+ astra_mex_data2d('store', reconstruction_id, 0);
+ end
+
+ % fetch slice of sinogram
+ astra_mex_data2d('store', sinogram_id, sinogram(:,:,slice));
+
+ % fecth slice of mask
+ if numel(mask) > 0
+ astra_mex_data2d('store', mask_id, mask(:,:,slice));
+ end
+
+ % iterate
+ astra_mex_algorithm('iterate', alg_id, iterations);
+
+ % fetch data
+ V(:,:,slice) = astra_mex_data2d('get', reconstruction_id);
+
+ end
+
+ % correct attenuation factors for super-resolution
+ if this.superresolution > 1 && strcmp(this.gpu,'yes')
+ if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat')
+ if numel(mask) > 0
+ V(mask > 0) = V(mask > 0) ./ this.superresolution;
+ else
+ V = V ./ this.superresolution;
+ end
+ end
+ end
+
+ % garbage collection
+ astra_mex_algorithm('delete', alg_id);
+ astra_mex_data2d('delete', sinogram_id, reconstruction_id);
+ if numel(mask) > 0
+ astra_mex_data2d('delete', mask_id);
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ % Protected function: reconstruct (data in astra)
+ function V = reconstruct_c_astra(this, sinogram, V0, mask, iterations)
+
+ if this.initialized == 0
+ error('IterativeTomography not initialized');
+ end
+
+ if numel(V0) > 1 || numel(mask) > 1 || numel(sinogram) > 1
+ error('Not all required data is stored in the astra memory');
+ end
+
+ if numel(V0) == 0
+ V0 = astra_mex_data2d('create', '-vol', this.vol_geom, 0);
+ end
+
+ % parse method
+ method2 = upper(this.method);
+ if strcmp(method2, 'SART') || strcmp(method2, 'SART_CUDA')
+ iterations = iterations * astra_geom_size(this.proj_geom, 1);
+ elseif strcmp(method2, 'ART')
+ s = astra_geom_size(this.proj_geom);
+ iterations = iterations * s(1) * s(2);
+ end
+
+ % algorithm configuration
+ cfg = this.cfg_base;
+ cfg.ProjectionDataId = sinogram;
+ cfg.ReconstructionDataId = V0;
+ if numel(mask) > 0
+ cfg.option.ReconstructionMaskId = mask;
+ end
+ alg_id = astra_mex_algorithm('create', cfg);
+
+ % iterate
+ astra_mex_algorithm('iterate', alg_id, iterations);
+
+ % fetch data
+ V = V0;
+
+ % correct attenuation factors for super-resolution
+ if this.superresolution > 1
+ if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat')
+ if numel(mask) > 0
+ astra_data_op_masked('$1./s1', [V V], [this.superresolution this.superresolution], mask, this.gpu_core);
+ else
+ astra_data_op('$1./s1', [V V], [this.superresolution this.superresolution], this.gpu_core);
+ end
+ end
+ end
+
+ % garbage collection
+ astra_mex_algorithm('delete', alg_id);
+
+ end
+
+ %------------------------------------------------------------------
+ function V_out = selectROI(~, V_in)
+
+ if numel(V_in) == 1
+ cfg = astra_struct('RoiSelect_CUDA');
+ cfg.DataId = V_in;
+ alg_id = astra_mex_algorithm('create',cfg);
+ astra_mex_algorithm('run', alg_id);
+ astra_mex_algorithm('delete', alg_id);
+ V_out = V_in;
+ else
+ V_out = ROIselectfull(V_in, min([size(V_in,1), size(V_in,2)]));
+ end
+
+ end
+ %------------------------------------------------------------------
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/IterativeTomography3D.m b/matlab/algorithms/DART/IterativeTomography3D.m
new file mode 100644
index 0000000..3f89457
--- /dev/null
+++ b/matlab/algorithms/DART/IterativeTomography3D.m
@@ -0,0 +1,433 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef IterativeTomography3D < matlab.mixin.Copyable
+
+ % Algorithm class for 3D Iterative Tomography.
+
+ %----------------------------------------------------------------------
+ properties (SetAccess=public, GetAccess=public)
+ superresolution = 1; % SETTING: Volume upsampling factor.
+ proj_type = 'linear'; % SETTING: Projector type, only when gpu='no'.
+ method = 'SIRT3D_CUDA'; % SETTING: Iterative method (see ASTRA toolbox documentation).
+ gpu = 'yes'; % SETTING: Use gpu? {'yes', 'no'}
+ gpu_core = 0; % SETTING: Which gpu core to use? Only when gpu='yes'.
+ inner_circle = 'yes'; % SETTING: Do roi only? {'yes', 'no'}
+ image_size = []; % SETTING: Overwrite default reconstruction size. Only if no vol_geom is specified.
+ use_minc = 'no'; % SETTING: Use minimum constraint. {'no', 'yes'}
+ maxc = +Inf; % SETTING: Maximum constraint. +Inf means off.
+ end
+ %----------------------------------------------------------------------
+ properties (SetAccess=public, GetAccess=public)
+ sinogram = []; % DATA: Projection data.
+ proj_geom = []; % DATA: Projection geometry.
+ V = []; % DATA: Volume data. Also used to set initial estimate (optional).
+ vol_geom = []; % DATA: Volume geometry.
+ end
+ %----------------------------------------------------------------------
+ properties (SetAccess=private, GetAccess=public)
+ initialized = 0; % Is this object initialized?
+ end
+ %----------------------------------------------------------------------
+ properties (SetAccess=protected, GetAccess=protected)
+ proj_geom_sr = []; % PROTECTED: geometry of sinogram (with super-resolution)
+ proj_id = []; % PROTECTED: astra id of projector (when gpu='no')
+ proj_id_sr = []; % PROTECTED: astra id of super-resolution projector (when gpu='no')
+ cfg_base = struct(); % PROTECTED: base configuration structure for the reconstruction algorithm.
+ end
+ %----------------------------------------------------------------------
+
+ methods (Access=public)
+
+ %------------------------------------------------------------------
+ function this = IterativeTomography(varargin)
+ % Constructor
+ % >> tomography = IterativeTomography();
+ % >> tomography = IterativeTomography(base); base struct should contain fields 'sinogram' and 'proj_geom'.
+ % >> tomography = IterativeTomography(base_filename); mat-file should contain 'sinogram' and 'proj_geom'.
+ % >> tomography = IterativeTomography(proj_geom, vol_geom);
+ % >> tomography = IterativeTomography(sinogram, proj_geom);
+
+ % Input: IterativeTomography(base)
+ if nargin == 1
+ if ischar(varargin{1})
+ this.sinogram = load(varargin{1},'sinogram');
+ this.proj_geom = load(varargin{1},'proj_geom');
+ else
+ this.sinogram = varargin{1}.sinogram;
+ this.proj_geom = varargin{1}.proj_geom;
+ end
+ end
+ % Input: IterativeTomography(proj_geom, vol_geom)
+ if nargin == 2 && isstruct(varargin{1}) && isstruct(varargin{2})
+ this.proj_geom = varargin{1};
+ this.vol_geom = varargin{2};
+ % Input: IterativeTomography(sinogram, proj_geom)
+ elseif nargin == 2
+ this.sinogram = varargin{1};
+ this.proj_geom = varargin{2};
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ function delete(this)
+ % Destructor
+ % >> clear tomography;
+ if strcmp(this.gpu,'no') && numel(this.proj_id) > 0
+ astra_mex_projector('delete', this.proj_id, this.proj_id_sr);
+ end
+ end
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = tomography.getsettings();
+ settings.superresolution = this.superresolution;
+ settings.proj_type = this.proj_type;
+ settings.method = this.method;
+ settings.gpu = this.gpu;
+ settings.gpu_core = this.gpu_core;
+ settings.inner_circle = this.inner_circle;
+ settings.image_size = this.image_size;
+ settings.use_minc = this.use_minc;
+ settings.maxc = this.maxc;
+ end
+
+ %------------------------------------------------------------------
+ function ok = initialize(this)
+ % Initialize this object. Returns 1 if succesful.
+ % >> tomography.initialize();
+
+% % create projection geometry with super-resolution
+% this.proj_geom_sr = astra_geom_superresolution(this.proj_geom, this.superresolution);
+
+ % if no volume geometry is specified by the user: create volume geometry
+ if numel(this.vol_geom) == 0
+ if numel(this.image_size) < 2
+ this.image_size(1) = this.proj_geom.DetectorRowCount;
+ this.image_size(2) = this.proj_geom.DetectorColCount;
+ end
+ this.vol_geom = astra_create_vol_geom(this.proj_geom.DetectorColCount, this.proj_geom.DetectorColCount, this.proj_geom.DetectorRowCount);
+ else
+ this.image_size(1) = this.vol_geom.GridRowCount;
+ this.image_size(2) = this.vol_geom.GridColCount;
+ end
+
+ % create projector
+ if strcmp(this.gpu, 'no')
+ this.proj_id = astra_create_projector(this.proj_type, this.proj_geom, this.vol_geom);
+ this.proj_id_sr = astra_create_projector(this.proj_type, this.proj_geom_sr, this.vol_geom);
+ end
+
+ % create reconstruction configuration
+ this.cfg_base = astra_struct(upper(this.method));
+ if strcmp(this.gpu,'no')
+ this.cfg_base.ProjectorId = this.proj_id;
+ this.cfg_base.ProjectionGeometry = this.proj_geom;
+ this.cfg_base.ReconstructionGeometry = this.vol_geom;
+ this.cfg_base.option.ProjectionOrder = 'random';
+ end
+ this.cfg_base.option.DetectorSuperSampling = this.superresolution;
+ %this.cfg_base.option.DetectorSuperSampling = 8;
+ if strcmp(this.gpu,'yes')
+ this.cfg_base.option.GPUindex = this.gpu_core;
+ end
+ this.cfg_base.option.UseMinConstraint = this.use_minc;
+ if ~isinf(this.maxc)
+ this.cfg_base.option.UseMaxConstraint = 'yes';
+ this.cfg_base.option.MaxConstraintValue = this.maxc;
+ end
+
+ this.initialized = 1;
+ ok = this.initialized;
+ end
+
+ %------------------------------------------------------------------
+ function P = project(this, volume)
+ % Compute forward projection.
+ % Stores sinogram in tomography.sinogram if it is still empty.
+ % >> P = tomography.project(); projects 'tomography.V'.
+ % >> P = tomography.project(volume); projects 'volume'.
+
+ if ~this.initialized
+ this.initialize();
+ end
+
+ if nargin == 1 % tomography.project();
+ P = this.project_c(this.V);
+
+ elseif nargin == 2 % tomography.project(volume);
+ P = this.project_c(volume);
+ end
+
+ % store
+ if numel(this.sinogram) == 0
+ this.sinogram = P;
+ end
+ end
+
+ %------------------------------------------------------------------
+ function V = reconstruct(this, iterations)
+ % Compute reconstruction.
+ % Uses tomography.sinogram
+ % Initial solution (if available) should be stored in tomography.V
+ % >> V = tomography.reconstruct(iterations);
+
+ if ~this.initialized
+ this.initialize();
+ end
+
+ this.V = this.reconstruct_c(this.sinogram, this.V, [], iterations);
+ if strcmp(this.inner_circle,'yes')
+ this.V = this.selectROI(this.V);
+ end
+ V = this.V;
+ end
+
+ %------------------------------------------------------------------
+ function I = reconstructMask(this, mask, iterations)
+ % Compute reconstruction with mask.
+ % Uses tomography.sinogram
+ % Initial solution (if available) should be stored in tomography.V
+ % >> V = tomography.reconstructMask(mask, iterations);
+
+ if ~this.initialized
+ this.initialize();
+ end
+
+ if strcmp(this.inner_circle,'yes')
+ mask = this.selectROI(mask);
+ end
+ I = this.reconstruct_c(this.sinogram, this.V, mask, iterations);
+ end
+ %------------------------------------------------------------------
+
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access = protected)
+
+ %------------------------------------------------------------------
+ % Protected function: create FP
+ function sinogram = project_c(this, volume)
+
+ if this.initialized == 0
+ error('IterativeTomography not initialized');
+ end
+
+ % data is stored in astra memory
+ if numel(volume) == 1
+
+ if strcmp(this.gpu, 'yes')
+ sinogram_tmp = astra_create_sino_cuda(volume, this.proj_geom_sr, this.vol_geom, this.gpu_core);
+ else
+ sinogram_tmp = astra_create_sino(volume, this.proj_id);
+ end
+
+ % sinogram downsampling
+ if this.superresolution > 1
+ sinogram_data = astra_mex_data2d('get', sinogram_tmp);
+ astra_mex_data2d('delete', sinogram_tmp);
+ sinogram_data = downsample_sinogram(sinogram_data, this.superresolution);
+ %if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat')
+ % sinogram = sinogram / this.superresolution;
+ %end
+ sinogram = astra_mex_data2d('create','sino', this.proj_geom, sinogram_data);
+ else
+ sinogram = sinogram_tmp;
+ end
+
+ % data is stored in matlab memory
+ else
+
+ [tmp_id, sinogram] = astra_create_sino3d_cuda(volume, this.proj_geom, this.vol_geom);
+ astra_mex_data3d('delete', tmp_id);
+
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ % Protected function: reconstruct
+ function V = reconstruct_c(this, sinogram, V0, mask, iterations)
+
+ if this.initialized == 0
+ error('IterativeTomography not initialized');
+ end
+
+ % data is stored in astra memory
+ if numel(sinogram) == 1
+ V = this.reconstruct_c_astra(sinogram, V0, mask, iterations);
+
+ % data is stored in matlab memory
+ else
+ V = this.reconstruct_c_matlab(sinogram, V0, mask, iterations);
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ % Protected function: reconstruct (data in matlab)
+ function V = reconstruct_c_matlab(this, sinogram, V0, mask, iterations)
+
+ if this.initialized == 0
+ error('IterativeTomography not initialized');
+ end
+
+ % parse method
+ method2 = upper(this.method);
+ if strcmp(method2, 'SART') || strcmp(method2, 'SART_CUDA')
+ iterations = iterations * size(sinogram,1);
+ elseif strcmp(method2, 'ART')
+ iterations = iterations * numel(sinogram);
+ end
+
+ % create data objects
+% V = zeros(this.vol_geom.GridRowCount, this.vol_geom.GridColCount, size(sinogram,3));
+ reconstruction_id = astra_mex_data3d('create', '-vol', this.vol_geom);
+ sinogram_id = astra_mex_data3d('create', '-proj3d', this.proj_geom);
+ if numel(mask) > 0
+ mask_id = astra_mex_data3d('create', '-vol', this.vol_geom);
+ end
+
+ % algorithm configuration
+ cfg = this.cfg_base;
+ cfg.ProjectionDataId = sinogram_id;
+ cfg.ReconstructionDataId = reconstruction_id;
+ if numel(mask) > 0
+ cfg.option.ReconstructionMaskId = mask_id;
+ end
+ alg_id = astra_mex_algorithm('create', cfg);
+
+% % loop slices
+% for slice = 1:size(sinogram,3)
+
+ % fetch slice of initial reconstruction
+ if numel(V0) > 0
+ astra_mex_data3d('store', reconstruction_id, V0);
+ else
+ astra_mex_data3d('store', reconstruction_id, 0);
+ end
+
+ % fetch slice of sinogram
+ astra_mex_data3d('store', sinogram_id, sinogram);
+
+ % fecth slice of mask
+ if numel(mask) > 0
+ astra_mex_data3d('store', mask_id, mask);
+ end
+
+ % iterate
+ astra_mex_algorithm('iterate', alg_id, iterations);
+
+ % fetch data
+ V = astra_mex_data3d('get', reconstruction_id);
+
+% end
+
+ % correct attenuation factors for super-resolution
+ if this.superresolution > 1 && strcmp(this.gpu,'yes')
+ if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat')
+ if numel(mask) > 0
+ V(mask > 0) = V(mask > 0) ./ this.superresolution;
+ else
+ V = V ./ this.superresolution;
+ end
+ end
+ end
+
+ % garbage collection
+ astra_mex_algorithm('delete', alg_id);
+ astra_mex_data3d('delete', sinogram_id, reconstruction_id);
+ if numel(mask) > 0
+ astra_mex_data3d('delete', mask_id);
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ % Protected function: reconstruct (data in astra)
+ function V = reconstruct_c_astra(this, sinogram, V0, mask, iterations)
+
+ if this.initialized == 0
+ error('IterativeTomography not initialized');
+ end
+
+ if numel(V0) > 1 || numel(mask) > 1 || numel(sinogram) > 1
+ error('Not all required data is stored in the astra memory');
+ end
+
+ if numel(V0) == 0
+ V0 = astra_mex_data2d('create', '-vol', this.vol_geom, 0);
+ end
+
+ % parse method
+ method2 = upper(this.method);
+ if strcmp(method2, 'SART') || strcmp(method2, 'SART_CUDA')
+ iterations = iterations * astra_geom_size(this.proj_geom, 1);
+ elseif strcmp(method2, 'ART')
+ s = astra_geom_size(this.proj_geom);
+ iterations = iterations * s(1) * s(2);
+ end
+
+ % algorithm configuration
+ cfg = this.cfg_base;
+ cfg.ProjectionDataId = sinogram;
+ cfg.ReconstructionDataId = V0;
+ if numel(mask) > 0
+ cfg.option.ReconstructionMaskId = mask;
+ end
+ alg_id = astra_mex_algorithm('create', cfg);
+
+ % iterate
+ astra_mex_algorithm('iterate', alg_id, iterations);
+
+ % fetch data
+ V = V0;
+
+ % correct attenuation factors for super-resolution
+ if this.superresolution > 1
+ if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat')
+ if numel(mask) > 0
+ astra_data_op_masked('$1./s1', [V V], [this.superresolution this.superresolution], mask, this.gpu_core);
+ else
+ astra_data_op('$1./s1', [V V], [this.superresolution this.superresolution], this.gpu_core);
+ end
+ end
+ end
+
+ % garbage collection
+ astra_mex_algorithm('delete', alg_id);
+
+ end
+
+ %------------------------------------------------------------------
+ function V_out = selectROI(~, V_in)
+
+ if numel(V_in) == 1
+ cfg = astra_struct('RoiSelect_CUDA');
+ cfg.DataId = V_in;
+ alg_id = astra_mex_algorithm('create',cfg);
+ astra_mex_algorithm('run', alg_id);
+ astra_mex_algorithm('delete', alg_id);
+ V_out = V_in;
+ else
+ V_out = ROIselectfull(V_in, min([size(V_in,1), size(V_in,2)]));
+ end
+
+ end
+ %------------------------------------------------------------------
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/Kernels.m b/matlab/algorithms/DART/Kernels.m
new file mode 100644
index 0000000..b5e3134
--- /dev/null
+++ b/matlab/algorithms/DART/Kernels.m
@@ -0,0 +1,68 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef Kernels
+ %KERNELS Summary of this class goes here
+ % Detailed explanation goes here
+
+ properties
+
+ end
+
+ methods(Static)
+
+ function K = BinaryPixelKernel(radius, conn)
+
+ if nargin < 2
+ conn = 8;
+ end
+
+ % 2D, 4conn
+ if conn == 4
+ K = [0 1 0; 1 1 1; 0 1 0];
+ for i = 2:radius
+ K = conv2(K,K);
+ end
+ K = double(K >= 1);
+
+ % 2D, 8conn
+ elseif conn == 8
+ K = ones(2*radius+1, 2*radius+1);
+
+ % 3D, 6conn
+ elseif conn == 6
+ K = zeros(3,3,3);
+ K(:,:,1) = [0 0 0; 0 1 0; 0 0 0];
+ K(:,:,2) = [0 1 0; 1 1 1; 0 1 0];
+ K(:,:,3) = [0 0 0; 0 1 0; 0 0 0];
+ for i = 2:radius
+ K = convn(K,K);
+ end
+ K = double(K >= 1);
+
+ % 2D, 27conn
+ elseif conn == 26
+ K = ones(2*radius+1, 2*radius+1, 2*radius+1);
+
+ else
+ disp('Invalid conn')
+ end
+ end
+
+
+
+
+
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/MaskingDefault.m b/matlab/algorithms/DART/MaskingDefault.m
new file mode 100644
index 0000000..6bd25a5
--- /dev/null
+++ b/matlab/algorithms/DART/MaskingDefault.m
@@ -0,0 +1,212 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef MaskingDefault < matlab.mixin.Copyable
+
+ % Default policy class for masking for DART.
+
+ %----------------------------------------------------------------------
+ properties (Access=public)
+
+ radius = 1; % SETTING: Radius of masking kernel.
+ conn = 8; % SETTING: Connectivity window. For 2D: 4 or 8. For 3D: 6 or 26.
+ edge_threshold = 1; % SETTING: Number of pixels in the window that should be different.
+ random = 0.1; % SETTING: Percentage of random points. Between 0 and 1.
+ gpu = 'yes'; % SETTING: Use gpu? {'yes', 'no'}
+ gpu_core = 0; % SETTING: Which gpu core to use, only when gpu='yes'.
+
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access=public)
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = DART.masking.getsettings();
+ settings.radius = this.radius;
+ settings.conn = this.conn;
+ settings.edge_threshold = this.edge_threshold;
+ settings.random = this.random;
+ end
+
+ %------------------------------------------------------------------
+ function Mask = apply(this, ~, S)
+ % Applies masking.
+ % >> Mask = DART.segmentation.apply(DART, S);
+
+ % 2D, one slice
+ if size(S,3) == 1
+ if strcmp(this.gpu,'yes')
+ Mask = this.apply_2D_gpu(S);
+ else
+ Mask = this.apply_2D(S);
+ end
+
+ % 3D, slice by slice
+ elseif this.conn == 4 || this.conn == 8
+ Mask = zeros(size(S));
+ for slice = 1:size(S,3)
+ if strcmp(this.gpu,'yes')
+ Mask(:,:,slice) = this.apply_2D_gpu(S(:,:,slice));
+ else
+ Mask(:,:,slice) = this.apply_2D(S(:,:,slice));
+ end
+ end
+
+ % 3D, full
+ else
+ if strcmp(this.gpu,'yes')
+ Mask = this.apply_3D_gpu(S);
+ else
+ Mask = this.apply_3D(S);
+ end
+ end
+
+ end
+
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access=protected)
+
+ %------------------------------------------------------------------
+ function Mask = apply_2D_gpu(this, S)
+
+ vol_geom = astra_create_vol_geom(size(S));
+ data_id = astra_mex_data2d('create', '-vol', vol_geom, S);
+ mask_id = astra_mex_data2d('create', '-vol', vol_geom, 0);
+
+ cfg = astra_struct('DARTMASK_CUDA');
+ cfg.SegmentationDataId = data_id;
+ cfg.MaskDataId = mask_id;
+ cfg.option.GPUindex = this.gpu_core;
+ cfg.option.Connectivity = this.conn;
+ cfg.option.Threshold = this.edge_threshold;
+ cfg.option.Radius = this.radius;
+
+ alg_id = astra_mex_algorithm('create',cfg);
+ astra_mex_algorithm('iterate',alg_id,1);
+ Mask = astra_mex_data2d('get', mask_id);
+
+ astra_mex_algorithm('delete', alg_id);
+ astra_mex_data2d('delete', data_id, mask_id);
+
+ % random
+ RandomField = double(rand(size(S)) < this.random);
+
+ % combine
+ Mask = or(Mask, RandomField);
+
+ end
+
+ %------------------------------------------------------------------
+ function Mask = apply_2D(this, S)
+
+ r = this.radius;
+ w = 2 * r + 1;
+
+ kernel = Kernels.BinaryPixelKernel(r, this.conn);
+
+ % edges
+ Xlarge = zeros(size(S,1)+w-1, size(S,2)+w-1);
+ Xlarge(1+r:end-r, 1+r:end-r) = S;
+
+ Edges = zeros(size(S));
+ for s = -r:r
+ for t = -r:r
+ if kernel(s+r+1, t+r+1) == 0
+ continue
+ end
+ Temp = abs(Xlarge(1+r:end-r, 1+r:end-r) - Xlarge(1+r+s:end-r+s, 1+r+t:end-r+t));
+ Edges(Temp > eps) = Edges(Temp > eps) + 1;
+ end
+ end
+
+ Edges = Edges > this.edge_threshold;
+
+ % random
+ RandomField = double(rand(size(S)) < this.random);
+
+ % combine
+ Mask = or(Edges, RandomField);
+
+ end
+
+ %------------------------------------------------------------------
+ function Mask = apply_3D(this, S)
+
+ r = this.radius;
+ w = 2 * r + 1;
+
+ kernel = Kernels.BinaryPixelKernel(r, this.conn);
+
+ % edges
+ Xlarge = zeros(size(S,1)+w-1, size(S,2)+w-1, size(S,3)+w-1);
+ Xlarge(1+r:end-r, 1+r:end-r, 1+r:end-r) = S;
+
+ Edges = zeros(size(S));
+ for s = -r:r
+ for t = -r:r
+ for u = -r:r
+ if kernel(s+r+1, t+r+1, u+r+1) == 0
+ continue
+ end
+ Temp = abs(Xlarge(1+r:end-r, 1+r:end-r, 1+r:end-r) - Xlarge(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u));
+ Edges(Temp > eps) = 1;
+ end
+ end
+ end
+
+ clear Xlarge;
+
+ % random
+ RandomField = double(rand(size(S)) < this.random);
+
+ % combine
+ Mask = or(Edges, RandomField);
+
+ end
+
+ %------------------------------------------------------------------
+ function Mask = apply_3D_gpu(this, S)
+
+ vol_geom = astra_create_vol_geom(size(S));
+ data_id = astra_mex_data3d('create', '-vol', vol_geom, S);
+
+ cfg = astra_struct('DARTMASK3D_CUDA');
+ cfg.SegmentationDataId = data_id;
+ cfg.MaskDataId = data_id;
+ cfg.option.GPUindex = this.gpu_core;
+ cfg.option.Connectivity = this.conn;
+ cfg.option.Threshold = this.edge_threshold;
+ cfg.option.Radius = this.radius;
+
+ alg_id = astra_mex_algorithm('create',cfg);
+ astra_mex_algorithm('iterate',alg_id,1);
+ Mask = astra_mex_data3d('get', data_id);
+
+ astra_mex_algorithm('delete', alg_id);
+ astra_mex_data3d('delete', data_id);
+
+ % random
+ RandomField = double(rand(size(S)) < this.random);
+
+ % combine
+ Mask = or(Mask, RandomField);
+
+ end
+
+ %------------------------------------------------------------------
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/MaskingGPU.m b/matlab/algorithms/DART/MaskingGPU.m
new file mode 100644
index 0000000..c4ef2b7
--- /dev/null
+++ b/matlab/algorithms/DART/MaskingGPU.m
@@ -0,0 +1,94 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef MaskingGPU < matlab.mixin.Copyable
+
+ % Policy class for masking for DART with GPU accelerated code (deprecated).
+
+ %----------------------------------------------------------------------
+ properties (Access=public)
+
+ radius = 1; % SETTING: Radius of masking kernel.
+ conn = 8; % SETTING: Connectivity window. For 2D: 4 or 8. For 3D: 6 or 26.
+ edge_threshold = 1; % SETTING: Number of pixels in the window that should be different.
+ gpu_core = 0; % SETTING:
+ random = 0.1; % SETTING: Percentage of random points. Between 0 and 1.
+
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access=public)
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = DART.masking.getsettings();
+ settings.radius = this.radius;
+ settings.conn = this.conn;
+ settings.edge_threshold = this.edge_threshold;
+ settings.random = this.random;
+ end
+
+ %------------------------------------------------------------------
+ function Mask = apply(this, ~, V_in)
+ % Applies masking.
+ % >> Mask = DART.segmentation.apply(DART, V_in);
+
+ % 2D, one slice
+ if size(V_in,3) == 1
+ Mask = this.apply_2D(V_in);
+
+ % 3D, slice by slice
+ elseif this.conn == 4 || this.conn == 8
+ Mask = zeros(size(V_in));
+ for slice = 1:size(V_in,3)
+ Mask(:,:,slice) = this.apply_2D(V_in(:,:,slice));
+ end
+
+ % 3D, full
+ else
+ error('Full 3D masking on GPU not implemented.')
+ end
+
+ end
+
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access=protected)
+
+ %------------------------------------------------------------------
+ function Mask = apply_2D(this, S)
+
+ vol_geom = astra_create_vol_geom(size(S));
+ data_id = astra_mex_data2d('create', '-vol', vol_geom, S);
+ mask_id = astra_mex_data2d('create', '-vol', vol_geom, 0);
+
+ cfg = astra_struct('DARTMASK_CUDA');
+ cfg.SegmentationDataId = data_id;
+ cfg.MaskDataId = mask_id;
+ cfg.option.GPUindex = this.gpu_core;
+ %cfg.option.Connectivity = this.conn;
+
+ alg_id = astra_mex_algorithm('create',cfg);
+ astra_mex_algorithm('iterate',alg_id,1);
+ Mask = astra_mex_data2d('get', mask_id);
+
+ astra_mex_algorithm('delete', alg_id);
+ astra_mex_data2d('delete', data_id, mask_id);
+
+ end
+ end
+
+
+
+end
+
diff --git a/matlab/algorithms/DART/OutputDefault.m b/matlab/algorithms/DART/OutputDefault.m
new file mode 100644
index 0000000..a34a430
--- /dev/null
+++ b/matlab/algorithms/DART/OutputDefault.m
@@ -0,0 +1,173 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef OutputDefault < matlab.mixin.Copyable
+
+ % Default policy class for output for DART.
+
+ properties (Access=public)
+
+ directory = ''; % SETTING: Directory to save output.
+ pre = ''; % SETTING: Prefix of output.
+
+ save_images = 'no'; % SETTING: Save the images. 'no', 'yes' (='S') OR {'S', 'I', 'Mask', 'P'}
+ save_results = 'no'; % SETTING: Save the results. 'yes', 'no' OR {'base', 'stats', 'settings', 'S', 'V', 'V0'}
+ save_object = 'no'; % SETTING: Save the DART object. {'no','yes'}
+
+ save_interval = 1; % SETTING: # DART iteration between saves.
+ save_images_interval = []; % SETTING: Overwrite interval for save_images.
+ save_results_interval = []; % SETTING: Overwrite interval for save_results.
+ save_object_interval = []; % SETTING: Overwrite interval for save_object.
+
+ slices = 1; % SETTING: In case of 3D, which slices to save?
+
+ verbose = 'no'; % SETTING: Verbose? {'no','yes'}
+
+ end
+
+ methods (Access=public)
+
+ %------------------------------------------------------------------
+ function pre_initial_iteration(this, ~)
+ if strcmp(this.verbose,'yes')
+ tic
+ fprintf(1, 'initial iteration...');
+ end
+ end
+
+ %------------------------------------------------------------------
+ function post_initial_iteration(this, ~)
+ if strcmp(this.verbose,'yes')
+ t = toc;
+ fprintf(1, 'done in %f s.\n', t);
+ end
+ end
+
+ %------------------------------------------------------------------
+ function pre_iteration(this, DART)
+ if strcmp(this.verbose,'yes')
+ tic;
+ fprintf(1, '%s dart iteration %d...', this.pre, DART.iterationcount);
+ end
+ end
+
+ %------------------------------------------------------------------
+ function post_iteration(this, DART)
+
+ % print output
+ if strcmp(this.verbose,'yes')
+ t = toc;
+ s = DART.statistics.tostring(DART.stats);
+ fprintf(1, 'done in %0.2fs %s.\n', t, s);
+ end
+
+ % save DART object
+ if do_object(this, DART)
+ save(sprintf('%s%sobject_%i.mat', this.directory, this.pre, DART.iterationcount), '-v7.3', 'DART');
+ end
+
+ % save .mat
+ if do_results(this, DART)
+ base = DART.base;
+ stats = DART.stats;
+ S = DART.S;
+ V = DART.V;
+ V0 = DART.V0;
+ settings = DART.getsettings();
+ if ~iscell(this.save_results)
+ save(sprintf('%s%sresults_%i.mat', this.directory, this.pre, DART.iterationcount), '-v7.3', 'base', 'stats', 'S', 'V', 'V0', 'settings');
+ else
+ string = [];
+ for i = 1:numel(this.save_results)
+ string = [string this.save_results{i} '|'];
+ end
+ save(sprintf('%s%sresults_%i.mat', this.directory, this.pre, DART.iterationcount), '-v7.3', '-regexp', string(1:end-1));
+ end
+ end
+
+ % save images
+ if do_images(this, DART)
+
+ if ~iscell(this.save_images) && strcmp(this.save_images, 'yes')
+ output_image(this, DART, 'S')
+ elseif iscell(this.save_images)
+ for i = 1:numel(this.save_images)
+ output_image(this, DART, this.save_images{i});
+ end
+ end
+
+ end
+
+ end
+ %------------------------------------------------------------------
+
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access=private)
+
+ function output_image(this, DART, data)
+ % 2D
+ if numel(size(DART.S)) == 2
+ eval(['imwritesc(DART.' data ', sprintf(''%s%s' data '_%i.png'', this.directory, this.pre, DART.iterationcount))']);
+ % 3D
+ elseif numel(size(DART.S)) == 3
+ for slice = this.slices
+ eval(['imwritesc(DART.' data '(:,:,slice), sprintf(''%s%s' data '_%i_slice%i.png'', this.directory, this.pre, DART.iterationcount, slice))']);
+ end
+ end
+ end
+
+ %------------------------------------------------------------------
+ function out = do_object(this, DART)
+ if strcmp(this.save_object,'no')
+ out = 0;
+ return
+ end
+ if numel(this.save_object_interval) == 0 && mod(DART.iterationcount, this.save_interval) == 0
+ out = 1;
+ elseif mod(DART.iterationcount, this.save_object_interval) == 0
+ out = 1;
+ else
+ out = 0;
+ end
+ end
+ %------------------------------------------------------------------
+ function out = do_results(this, DART)
+ if strcmp(this.save_results,'no')
+ out = 0;
+ return
+ end
+ if numel(this.save_results_interval) == 0 && mod(DART.iterationcount, this.save_interval) == 0
+ out = 1;
+ elseif mod(DART.iterationcount, this.save_results_interval) == 0
+ out = 1;
+ else
+ out = 0;
+ end
+ end
+
+ %------------------------------------------------------------------
+ function out = do_images(this, DART)
+ if numel(this.save_images_interval) == 0 && mod(DART.iterationcount, this.save_interval) == 0
+ out = 1;
+ elseif mod(DART.iterationcount, this.save_images_interval) == 0
+ out = 1;
+ else
+ out = 0;
+ end
+ end
+ %------------------------------------------------------------------
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/SegmentationDefault.m b/matlab/algorithms/DART/SegmentationDefault.m
new file mode 100644
index 0000000..c1d7d99
--- /dev/null
+++ b/matlab/algorithms/DART/SegmentationDefault.m
@@ -0,0 +1,55 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef SegmentationDefault < matlab.mixin.Copyable
+
+ % Default policy class for segmentation for DART.
+
+ %----------------------------------------------------------------------
+ properties (Access=public)
+ rho = []; % SETTING: Grey levels.
+ tau = []; % SETTING: Threshold values.
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access=public)
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = DART.segmentation.getsettings();
+ settings.rho = this.rho;
+ settings.tau = this.tau;
+ end
+
+ %------------------------------------------------------------------
+ function this = estimate_grey_levels(this, ~, ~)
+ % Estimates grey levels
+ % >> DART.segmentation.estimate_grey_levels();
+ end
+
+ %------------------------------------------------------------------
+ function V_out = apply(this, ~, V_in)
+ % Applies segmentation.
+ % >> V_out = DART.segmentation.apply(DART, V_in);
+
+ V_out = ones(size(V_in)) * this.rho(1);
+ for n = 2:length(this.rho)
+ V_out(this.tau(n-1) < V_in) = this.rho(n);
+ end
+
+ end
+ %------------------------------------------------------------------
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/SmoothingDefault.m b/matlab/algorithms/DART/SmoothingDefault.m
new file mode 100644
index 0000000..58a8baa
--- /dev/null
+++ b/matlab/algorithms/DART/SmoothingDefault.m
@@ -0,0 +1,179 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef SmoothingDefault < matlab.mixin.Copyable
+
+ % Default policy class for smoothing for DART.
+
+ %----------------------------------------------------------------------
+ properties (Access=public)
+ radius = 1; % SETTING: Radius of smoothing kernel.
+ b = 0.1; % SETTING: Intensity of smoothing. Between 0 and 1.
+ full3d = 'yes'; % SETTING: smooth in 3D? {'yes','no'}
+ gpu = 'yes'; % SETTING: Use gpu? {'yes', 'no'}
+ gpu_core = 0; % SETTING: Which gpu core to use, only when gpu='yes'.
+ end
+
+
+ %----------------------------------------------------------------------
+ methods (Access=public)
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = DART.smoothing.getsettings();
+ settings.radius = this.radius;
+ settings.b = this.b;
+ settings.full3d = this.full3d;
+ end
+
+ %------------------------------------------------------------------
+ function V_out = apply(this, ~, V_in)
+ % Applies smoothing.
+ % >> V_out = DART.smoothing.apply(DART, V_in);
+
+ % 2D, one slice
+ if size(V_in,3) == 1
+ if strcmp(this.gpu,'yes')
+ V_out = this.apply_2D_gpu(V_in);
+ else
+ V_out = this.apply_2D(V_in);
+ end
+
+ % 3D, slice by slice
+ elseif ~strcmp(this.full3d,'yes')
+ V_out = zeros(size(V_in));
+ for slice = 1:size(V_in,3)
+ if strcmp(this.gpu,'yes')
+ V_out(:,:,slice) = this.apply_2D_gpu(V_in(:,:,slice));
+ else
+ V_out(:,:,slice) = this.apply_2D(V_in(:,:,slice));
+ end
+ end
+
+ % 3D, full
+ else
+ if strcmp(this.gpu,'yes')
+ V_out = this.apply_3D_gpu(V_in);
+ else
+ V_out = this.apply_3D(V_in);
+ end
+ end
+
+ end
+
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access=protected)
+
+ %------------------------------------------------------------------
+ function V_out = apply_2D(this, V_in)
+
+ r = this.radius;
+ w = 2 * r + 1;
+
+ % Set Kernel
+ K = ones(w) * this.b / (w.^2-1); % edges
+ K(r+1,r+1) = 1 - this.b; % center
+
+ % output window
+ V_out = zeros(size(V_in,1) + w-1, size(V_in,2) + w - 1);
+
+ % blur convolution
+ for s = -r:r
+ for t = -r:r
+ V_out(1+r+s:end-r+s, 1+r+t:end-r+t) = V_out(1+r+s:end-r+s, 1+r+t:end-r+t) + K(r+1+s, r+1+t) * V_in;
+ end
+ end
+
+ % shrink output window
+ V_out = V_out(1+r:end-r, 1+r:end-r);
+
+ end
+
+ %------------------------------------------------------------------
+ function V_out = apply_2D_gpu(this, V_in)
+
+ vol_geom = astra_create_vol_geom(size(V_in));
+ in_id = astra_mex_data2d('create', '-vol', vol_geom, V_in);
+ out_id = astra_mex_data2d('create', '-vol', vol_geom, 0);
+
+ cfg = astra_struct('DARTSMOOTHING_CUDA');
+ cfg.InDataId = in_id;
+ cfg.OutDataId = out_id;
+ cfg.option.Intensity = this.b;
+ cfg.option.Radius = this.radius;
+ cfg.option.GPUindex = this.gpu_core;
+
+ alg_id = astra_mex_algorithm('create',cfg);
+ astra_mex_algorithm('iterate',alg_id,1);
+ V_out = astra_mex_data2d('get', out_id);
+
+ astra_mex_algorithm('delete', alg_id);
+ astra_mex_data2d('delete', in_id, out_id);
+
+ end
+
+ %------------------------------------------------------------------
+ function I_out = apply_3D(this, I_in)
+
+ r = this.radius;
+ w = 2 * r + 1;
+
+ % Set Kernel
+ K = ones(w,w,w) * this.b / (w.^3-1); % edges
+ K(r+1,r+1,r+1) = 1 - this.b; % center
+
+ % output window
+ I_out = zeros(size(I_in,1)+w-1, size(I_in,2)+w-1, size(I_in,3)+w-1);
+
+ % blur convolution
+ for s = -r:r
+ for t = -r:r
+ for u = -r:r
+ I_out(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u) = I_out(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u) + K(r+1+s, r+1+t, r+1+u) * I_in;
+ end
+ end
+ end
+
+ % shrink output window
+ I_out = I_out(1+r:end-r, 1+r:end-r, 1+r:end-r);
+
+ end
+
+ %------------------------------------------------------------------
+ function V_out = apply_3D_gpu(this, V_in)
+
+ vol_geom = astra_create_vol_geom(size(V_in));
+ data_id = astra_mex_data3d('create', '-vol', vol_geom, V_in);
+
+ cfg = astra_struct('DARTSMOOTHING3D_CUDA');
+ cfg.InDataId = data_id;
+ cfg.OutDataId = data_id;
+ cfg.option.Intensity = this.b;
+ cfg.option.Radius = this.radius;
+ cfg.option.GPUindex = this.gpu_core;
+
+ alg_id = astra_mex_algorithm('create',cfg);
+ astra_mex_algorithm('iterate', alg_id, 1);
+ V_out = astra_mex_data3d('get', data_id);
+
+ astra_mex_algorithm('delete', alg_id);
+ astra_mex_data3d('delete', data_id);
+
+ end
+ %------------------------------------------------------------------
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/SmoothingGPU.m b/matlab/algorithms/DART/SmoothingGPU.m
new file mode 100644
index 0000000..857da37
--- /dev/null
+++ b/matlab/algorithms/DART/SmoothingGPU.m
@@ -0,0 +1,119 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef SmoothingGPU < matlab.mixin.Copyable
+
+ % Default policy class for smoothing for DART.
+
+ %----------------------------------------------------------------------
+ properties (Access=public)
+ radius = 1; % SETTING: Radius of smoothing kernel.
+ b = 0.1; % SETTING: Intensity of smoothing. Between 0 and 1.
+ full3d = 'yes'; % SETTING: smooth in 3D? {'yes','no'}
+ gpu_core = 0; % SETTING:
+ end
+
+
+ %----------------------------------------------------------------------
+ methods (Access=public)
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = DART.smoothing.getsettings();
+ settings.radius = this.radius;
+ settings.b = this.b;
+ settings.full3d = this.full3d;
+ end
+
+ %------------------------------------------------------------------
+ function V_out = apply(this, ~, V_in)
+ % Applies smoothing.
+ % >> V_out = DART.smoothing.apply(DART, V_in);
+
+ % 2D, one slice
+ if size(V_in,3) == 1
+ V_out = this.apply_2D(V_in);
+
+ % 3D, slice by slice
+ elseif ~strcmp(this.full3d,'yes')
+ V_out = zeros(size(V_in));
+ for slice = 1:size(V_in,3)
+ V_out(:,:,slice) = this.apply_2D(V_in(:,:,slice));
+ end
+
+ % 3D, full
+ else
+ V_out = this.apply_3D(V_in);
+ end
+
+ end
+
+ end
+
+ %----------------------------------------------------------------------
+ methods (Access=protected)
+
+ %------------------------------------------------------------------
+ function V_out = apply_2D(this, V_in)
+
+ vol_geom = astra_create_vol_geom(size(V_in));
+ in_id = astra_mex_data2d('create', '-vol', vol_geom, V_in);
+ out_id = astra_mex_data2d('create', '-vol', vol_geom, 0);
+
+ cfg = astra_struct('DARTSMOOTHING_CUDA');
+ cfg.InDataId = in_id;
+ cfg.OutDataId = out_id;
+ cfg.Intensity = this.b;
+ cfg.option.GPUindex = this.gpu_core;
+
+ alg_id = astra_mex_algorithm('create',cfg);
+ astra_mex_algorithm('iterate',alg_id,1);
+ V_out = astra_mex_data2d('get', out_id);
+
+ astra_mex_algorithm('delete', alg_id);
+ astra_mex_data2d('delete', in_id, out_id);
+
+
+ end
+
+ %------------------------------------------------------------------
+ function I_out = apply_3D(this, I_in)
+
+ r = this.radius;
+ w = 2 * r + 1;
+
+ % Set Kernel
+ K = ones(w,w,w) * this.b / (w.^3-1); % edges
+ K(r+1,r+1,r+1) = 1 - this.b; % center
+
+ % output window
+ I_out = zeros(size(I_in,1)+w-1, size(I_in,2)+w-1, size(I_in,3)+w-1);
+
+ % blur convolution
+ for s = -r:r
+ for t = -r:r
+ for u = -r:r
+ I_out(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u) = I_out(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u) + K(r+1+s, r+1+t, r+1+u) * I_in;
+ end
+ end
+ end
+
+ % shrink output window
+ I_out = I_out(1+r:end-r, 1+r:end-r, 1+r:end-r);
+
+ end
+ %------------------------------------------------------------------
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/StatisticsDefault.m b/matlab/algorithms/DART/StatisticsDefault.m
new file mode 100644
index 0000000..7822c5f
--- /dev/null
+++ b/matlab/algorithms/DART/StatisticsDefault.m
@@ -0,0 +1,72 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef StatisticsDefault < matlab.mixin.Copyable
+
+ % Default policy class for statistics for DART.
+
+ properties (Access=public)
+ pixel_error = 'yes'; % SETTING: Store pixel error? {'yes','no'}
+ proj_diff = 'yes'; % SETTING: Store projection difference? {'yes','no'}
+ timing = 'yes'; % SETTING: Store timings? {'yes','no'}
+ end
+
+
+ methods (Access=public)
+
+ %------------------------------------------------------------------
+ function stats = apply(this, DART)
+ % Applies statistics.
+ % >> stats = DART.statistics.apply(DART);
+
+ stats = DART.stats;
+
+ % timing
+ if strcmp(this.timing, 'yes')
+ stats.timing(DART.iterationcount) = toc(DART.start_tic);
+ end
+
+ % pixel error
+ if strcmp(this.pixel_error, 'yes') && isfield(DART.base,'phantom')
+ [stats.rnmp, stats.nmp] = compute_rnmp(DART.base.phantom, DART.S);
+ stats.rnmp_hist(DART.iterationcount) = stats.rnmp;
+ stats.nmp_hist(DART.iterationcount) = stats.nmp;
+ end
+
+ % projection difference
+ if strcmp(this.proj_diff, 'yes')
+ new_sino = DART.tomography.createForwardProjection(DART, DART.S);
+ stats.proj_diff = sum((new_sino(:) - DART.base.sinogram(:)) .^2 ) ./ (sum(DART.base.sinogram(:)) );
+ stats.proj_diff_hist(DART.iterationcount) = stats.proj_diff;
+ end
+
+ end
+
+ %------------------------------------------------------------------
+ function s = tostring(~, stats)
+ % To string.
+ % >> stats = DART.statistics.apply(stats);
+
+ s = '';
+ if isfield(stats, 'nmp')
+ s = sprintf('%s [%d]', s, stats.nmp);
+ end
+ if isfield(stats, 'proj_diff')
+ s = sprintf('%s {%0.2d}', s, stats.proj_diff);
+ end
+
+ end
+ %------------------------------------------------------------------
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/TomographyDefault.m b/matlab/algorithms/DART/TomographyDefault.m
new file mode 100644
index 0000000..4db3905
--- /dev/null
+++ b/matlab/algorithms/DART/TomographyDefault.m
@@ -0,0 +1,73 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef TomographyDefault < IterativeTomography
+
+ % Policy class for tomography for DART.
+
+ %----------------------------------------------------------------------
+ properties (Access=public)
+ t = 5; % SETTING: # ARMiterations, each DART iteration.
+ t0 = 100; % SETTING: # ARM iterations at DART initialization.
+ end
+ %----------------------------------------------------------------------
+
+ methods
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = DART.tomography.getsettings();
+% settings = getsettings@IterativeTomography();
+ settings.t = this.t;
+ settings.t0 = this.t0;
+ end
+
+ %------------------------------------------------------------------
+ function initialize(this, DART)
+ % Initializes this object.
+ % >> DART.tomography.initialize();
+ this.proj_geom = DART.base.proj_geom;
+ this.initialize@IterativeTomography();
+ end
+
+ %------------------------------------------------------------------
+ function P = createForwardProjection(this, ~, volume)
+ % Compute forward projection.
+ % >> DART.tomography.createForwardProjection(DART, volume);
+ P = this.project_c(volume);
+ end
+
+ %------------------------------------------------------------------
+ function I = createReconstruction(this, ~, sinogram, V0, mask)
+ % Compute reconstruction (with mask).
+ % >> DART.tomography.createReconstruction(DART, sinogram, V0, mask);
+ if strcmp(this.inner_circle,'yes')
+ mask = ROIselectfull(mask, size(mask,1));
+ end
+ I = this.reconstruct_c(sinogram, V0, mask, this.t);
+ end
+
+ %------------------------------------------------------------------
+ function I = createInitialReconstruction(this, ~, sinogram)
+ % Compute reconstruction (initial).
+ % >> DART.tomography.createInitialReconstruction(DART, sinogram);
+ I = this.reconstruct_c(sinogram, [], [], this.t0);
+ if strcmp(this.inner_circle,'yes')
+ I = ROIselectfull(I, size(I,1));
+ end
+ end
+ %------------------------------------------------------------------
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/TomographyDefault3D.m b/matlab/algorithms/DART/TomographyDefault3D.m
new file mode 100644
index 0000000..2be1b17
--- /dev/null
+++ b/matlab/algorithms/DART/TomographyDefault3D.m
@@ -0,0 +1,73 @@
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%
+% Author of this DART Algorithm: Wim van Aarle
+
+
+classdef TomographyDefault3D < IterativeTomography3D
+
+ % Policy class for 3D tomography for DART.
+
+ %----------------------------------------------------------------------
+ properties (Access=public)
+ t = 5; % SETTING: # ARMiterations, each DART iteration.
+ t0 = 100; % SETTING: # ARM iterations at DART initialization.
+ end
+ %----------------------------------------------------------------------
+
+ methods
+
+ %------------------------------------------------------------------
+ function settings = getsettings(this)
+ % Returns a structure containing all settings of this object.
+ % >> settings = DART.tomography.getsettings();
+% settings = getsettings@IterativeTomography();
+ settings.t = this.t;
+ settings.t0 = this.t0;
+ end
+
+ %------------------------------------------------------------------
+ function initialize(this, DART)
+ % Initializes this object.
+ % >> DART.tomography.initialize();
+ this.proj_geom = DART.base.proj_geom;
+ this.initialize@IterativeTomography3D();
+ end
+
+ %------------------------------------------------------------------
+ function P = createForwardProjection(this, ~, volume)
+ % Compute forward projection.
+ % >> DART.tomography.createForwardProjection(DART, volume);
+ P = this.project_c(volume);
+ end
+
+ %------------------------------------------------------------------
+ function I = createReconstruction(this, ~, sinogram, V0, mask)
+ % Compute reconstruction (with mask).
+ % >> DART.tomography.createReconstruction(DART, sinogram, V0, mask);
+ if strcmp(this.inner_circle,'yes')
+ mask = ROIselectfull(mask, size(mask,1));
+ end
+ I = this.reconstruct_c(sinogram, V0, mask, this.t);
+ end
+
+ %------------------------------------------------------------------
+ function I = createInitialReconstruction(this, ~, sinogram)
+ % Compute reconstruction (initial).
+ % >> DART.tomography.createInitialReconstruction(DART, sinogram);
+ I = this.reconstruct_c(sinogram, [], [], this.t0);
+ if strcmp(this.inner_circle,'yes')
+ I = ROIselectfull(I, size(I,1));
+ end
+ end
+ %------------------------------------------------------------------
+
+ end
+
+end
+
diff --git a/matlab/algorithms/DART/examples/cylinders.png b/matlab/algorithms/DART/examples/cylinders.png
new file mode 100644
index 0000000..8d1c0b2
--- /dev/null
+++ b/matlab/algorithms/DART/examples/cylinders.png
Binary files differ
diff --git a/matlab/algorithms/DART/examples/example1.m b/matlab/algorithms/DART/examples/example1.m
new file mode 100644
index 0000000..daa3ce8
--- /dev/null
+++ b/matlab/algorithms/DART/examples/example1.m
@@ -0,0 +1,79 @@
+clear all;
+
+addpath('..');
+
+%
+% Example 1: parallel beam, three slices.
+%
+
+% Configuration
+proj_count = 20;
+slice_count = 3;
+dart_iterations = 20;
+filename = 'cylinders.png';
+outdir = './';
+prefix = 'example1';
+rho = [0, 1];
+tau = 0.5;
+gpu_core = 0;
+
+% Load phantom.
+I = double(imread(filename)) / 255;
+
+% Create projection and volume geometries.
+det_count = size(I, 1);
+angles = linspace(0, pi - pi / proj_count, proj_count);
+proj_geom = astra_create_proj_geom('parallel3d', 1, 1, slice_count, det_count, angles);
+vol_geom = astra_create_vol_geom(det_count, det_count, 1);
+
+% Create sinogram.
+[sinogram_id, sinogram] = astra_create_sino3d_cuda(I, proj_geom, vol_geom);
+astra_mex_data3d('delete', sinogram_id);
+
+%
+% DART
+%
+
+base.sinogram = sinogram;
+base.proj_geom = proj_geom;
+
+D = DARTalgorithm(base);
+
+D.tomography = TomographyDefault3D();
+D.tomography.t0 = 100;
+D.tomography.t = 10;
+D.tomography.method = 'SIRT3D_CUDA';
+D.tomography.gpu_core = gpu_core;
+D.tomography.use_minc = 'yes';
+% D.tomography.maxc = 0.003; % Not a sensible value, just for demonstration.
+
+D.segmentation.rho = rho;
+D.segmentation.tau = tau;
+
+D.smoothing.b = 0.1;
+D.smoothing.full3d = 'yes';
+D.smoothing.gpu_core = gpu_core;
+
+D.masking.random = 0.1;
+D.masking.conn = 6;
+D.masking.gpu_core = gpu_core;
+
+D.output.directory = outdir;
+D.output.pre = [prefix '_'];
+D.output.save_images = 'no';
+D.output.save_results = {'stats', 'settings', 'S', 'V'};
+D.output.save_interval = dart_iterations;
+D.output.verbose = 'yes';
+
+D.statistics.proj_diff = 'no';
+
+D.initialize();
+
+disp([D.output.directory D.output.pre]);
+
+D.iterate(dart_iterations);
+
+% Convert middle slice of final iteration to png.
+load([outdir '/' prefix '_results_' num2str(dart_iterations) '.mat']);
+imwritesc(D.S(:, :, round(slice_count / 2)), [outdir '/' prefix '_slice_2_S.png']);
+imwritesc(D.V(:, :, round(slice_count / 2)), [outdir '/' prefix '_slice_2_V.png']);
diff --git a/matlab/algorithms/DART/examples/example2.m b/matlab/algorithms/DART/examples/example2.m
new file mode 100644
index 0000000..8ee8cba
--- /dev/null
+++ b/matlab/algorithms/DART/examples/example2.m
@@ -0,0 +1,80 @@
+clear all;
+
+addpath('..');
+
+%
+% Example 2: cone beam, full cube.
+%
+
+% Configuration
+det_count = 128;
+proj_count = 45;
+slice_count = det_count;
+dart_iterations = 20;
+outdir = './';
+prefix = 'example2';
+rho = [0 0.5 1];
+tau = [0.25 0.75];
+gpu_core = 0;
+
+% Create phantom.
+% I = phantom3d([1 0.9 0.9 0.9 0 0 0 0 0 0; -0.5 0.8 0.8 0.8 0 0 0 0 0 0; -0.5 0.3 0.3 0.3 0 0 0 0 0 0], det_count);
+% save('phantom3d', 'I');
+load('phantom3d'); % Loads I.
+
+% Create projection and volume geometries.
+angles = linspace(0, pi - pi / proj_count, proj_count);
+proj_geom = astra_create_proj_geom('cone', 1, 1, slice_count, det_count, angles, 500, 0);
+vol_geom = astra_create_vol_geom(det_count, det_count, slice_count);
+
+% Create sinogram.
+[sinogram_id, sinogram] = astra_create_sino3d_cuda(I, proj_geom, vol_geom);
+astra_mex_data3d('delete', sinogram_id);
+
+%
+% DART
+%
+
+base.sinogram = sinogram;
+base.proj_geom = proj_geom;
+
+D = DARTalgorithm(base);
+
+D.tomography = TomographyDefault3D();
+D.tomography.t0 = 100;
+D.tomography.t = 10;
+D.tomography.method = 'SIRT3D_CUDA';
+D.tomography.gpu_core = gpu_core;
+D.tomography.use_minc = 'yes';
+% D.tomography.maxc = 0.003; % Not a sensible value, just for demonstration.
+
+D.segmentation.rho = rho;
+D.segmentation.tau = tau;
+
+D.smoothing.b = 0.1;
+D.smoothing.full3d = 'yes';
+D.smoothing.gpu_core = gpu_core;
+
+D.masking.random = 0.1;
+D.masking.conn = 6;
+D.masking.gpu_core = gpu_core;
+
+D.output.directory = outdir;
+D.output.pre = [prefix '_'];
+D.output.save_images = 'no';
+D.output.save_results = {'stats', 'settings', 'S', 'V'};
+D.output.save_interval = dart_iterations;
+D.output.verbose = 'yes';
+
+D.statistics.proj_diff = 'no';
+
+D.initialize();
+
+disp([D.output.directory D.output.pre]);
+
+D.iterate(dart_iterations);
+
+% Convert middle slice of final iteration to png.
+load([outdir '/' prefix '_results_' num2str(dart_iterations) '.mat']);
+imwritesc(D.S(:, :, round(slice_count / 2)), [outdir '/' prefix '_slice_2_S.png']);
+imwritesc(D.V(:, :, round(slice_count / 2)), [outdir '/' prefix '_slice_2_V.png']);
diff --git a/matlab/algorithms/DART/examples/example3.m b/matlab/algorithms/DART/examples/example3.m
new file mode 100644
index 0000000..f6e360e
--- /dev/null
+++ b/matlab/algorithms/DART/examples/example3.m
@@ -0,0 +1,79 @@
+clear all;
+
+addpath('..');
+
+%
+% Example 3: parallel beam, 2D
+%
+
+% Configuration
+proj_count = 30;
+dart_iterations = 20;
+filename = 'cylinders.png';
+outdir = './';
+prefix = 'example3';
+rho = [0, 1];
+tau = 0.5;
+gpu_core = 0;
+
+% Load phantom.
+I = double(imread(filename)) / 255;
+
+% Create projection and volume geometries.
+det_count = size(I, 1);
+angles = linspace(0, pi - pi / proj_count, proj_count);
+proj_geom = astra_create_proj_geom('parallel', 1, det_count, angles);
+vol_geom = astra_create_vol_geom(det_count, det_count);
+
+% Create sinogram.
+[sinogram_id, sinogram] = astra_create_sino_cuda(I, proj_geom, vol_geom);
+astra_mex_data2d('delete', sinogram_id);
+
+%
+% DART
+%
+
+base.sinogram = sinogram;
+base.proj_geom = proj_geom;
+
+D = DARTalgorithm(base);
+
+%D.tomography = TomographyDefault3D();
+D.tomography.t0 = 100;
+D.tomography.t = 10;
+D.tomography.method = 'SIRT_CUDA';
+D.tomography.proj_type = 'strip';
+D.tomography.gpu_core = gpu_core;
+D.tomography.use_minc = 'yes';
+% D.tomography.maxc = 0.003; % Not a sensible value, just for demonstration.
+
+D.segmentation.rho = rho;
+D.segmentation.tau = tau;
+
+D.smoothing.b = 0.1;
+D.smoothing.full3d = 'yes';
+D.smoothing.gpu_core = gpu_core;
+
+D.masking.random = 0.1;
+D.masking.conn = 6;
+D.masking.gpu_core = gpu_core;
+
+D.output.directory = outdir;
+D.output.pre = [prefix '_'];
+D.output.save_images = 'no';
+D.output.save_results = {'stats', 'settings', 'S', 'V'};
+D.output.save_interval = dart_iterations;
+D.output.verbose = 'yes';
+
+D.statistics.proj_diff = 'no';
+
+D.initialize();
+
+disp([D.output.directory D.output.pre]);
+
+D.iterate(dart_iterations);
+
+% Convert output of final iteration to png.
+load([outdir '/' prefix '_results_' num2str(dart_iterations) '.mat']);
+imwritesc(D.S, [outdir '/' prefix '_S.png']);
+imwritesc(D.V, [outdir '/' prefix '_V.png']);
diff --git a/matlab/algorithms/DART/examples/phantom3d.mat b/matlab/algorithms/DART/examples/phantom3d.mat
new file mode 100644
index 0000000..6d70c16
--- /dev/null
+++ b/matlab/algorithms/DART/examples/phantom3d.mat
Binary files differ
diff --git a/matlab/mex/astra_mex.cpp b/matlab/mex/astra_mex.cpp
new file mode 100644
index 0000000..4b77f76
--- /dev/null
+++ b/matlab/mex/astra_mex.cpp
@@ -0,0 +1,121 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#include <mex.h>
+#include "mexHelpFunctions.h"
+
+#include "astra/Globals.h"
+
+using namespace std;
+using namespace astra;
+
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex('credits');
+ *
+ * Print Credits
+ */
+void astra_mex_credits(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ cout << "All Scale Tomographic Reconstruction Antwerp Toolbox (ASTRA-Toolbox) was developed at the University of Antwerp by" << endl;
+ cout << " * Joost Batenburg, PhD" << endl;
+ cout << " * Gert Merckx" << endl;
+ cout << " * Willem Jan Palenstijn" << endl;
+ cout << " * Tom Roelandts" << endl;
+ cout << " * Prof. Dr. Jan Sijbers" << endl;
+ cout << " * Wim van Aarle" << endl;
+ cout << " * Sander van der Maar" << endl;
+ cout << " * Gert Van Gompel, PhD" << endl;
+}
+
+//-----------------------------------------------------------------------------------------
+/** use_cuda = astra_mex('use_cuda');
+ *
+ * Is CUDA enabled?
+ */
+void astra_mex_use_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(astra::cudaEnabled() ? 1 : 0);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** version_number = astra_mex('version');
+ *
+ * Fetch the version number of the toolbox.
+ */
+void astra_mex_version(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(astra::getVersion());
+ } else {
+ cout << "astra toolbox version " << astra::getVersionString() << endl;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+
+static void printHelp()
+{
+ mexPrintf("Please specify a mode of operation.\n");
+ mexPrintf(" Valid modes: version, use_cuda, credits\n");
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * ... = astra_mex(type,...);
+ */
+void mexFunction(int nlhs, mxArray* plhs[],
+ int nrhs, const mxArray* prhs[])
+{
+
+ // INPUT0: Mode
+ string sMode = "";
+ if (1 <= nrhs) {
+ sMode = mex_util_get_string(prhs[0]);
+ } else {
+ printHelp();
+ return;
+ }
+
+ // SWITCH (MODE)
+ if (sMode == std::string("version")) {
+ astra_mex_version(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("use_cuda")) {
+ astra_mex_use_cuda(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("credits")) {
+ astra_mex_credits(nlhs, plhs, nrhs, prhs);
+ } else {
+ printHelp();
+ }
+
+ return;
+}
+
+
diff --git a/matlab/mex/astra_mex_algorithm_c.cpp b/matlab/mex/astra_mex_algorithm_c.cpp
new file mode 100644
index 0000000..7476ba4
--- /dev/null
+++ b/matlab/mex/astra_mex_algorithm_c.cpp
@@ -0,0 +1,348 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+/** \file astra_mex_algorithm_c.cpp
+ *
+ * \brief Creates and manages algorithms (reconstruction,projection,...).
+ */
+#include <mex.h>
+#include "mexHelpFunctions.h"
+
+#define USE_MATLAB_UNDOCUMENTED
+
+#ifdef USE_MATLAB_UNDOCUMENTED
+extern "C" { bool utIsInterruptPending(); }
+
+#ifdef __linux__
+#define USE_PTHREADS_CTRLC
+#include <pthread.h>
+#else
+#include <boost/thread.hpp>
+#endif
+
+#endif
+
+
+
+#include "astra/Globals.h"
+
+#include "astra/AstraObjectManager.h"
+#include "astra/AstraObjectFactory.h"
+
+#include "astra/XMLNode.h"
+#include "astra/XMLDocument.h"
+
+using namespace std;
+using namespace astra;
+//-----------------------------------------------------------------------------------------
+/** id = astra_mex_algorithm('create', cfg);
+ *
+ * Create and configure a new algorithm object.
+ * cfg: MATLAB struct containing the configuration parameters, see doxygen documentation for details.
+ * id: identifier of the algorithm object as it is now stored in the astra-library.
+ */
+void astra_mex_algorithm_create(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ if (!mxIsStruct(prhs[1])) {
+ mexErrMsgTxt("Argument 1 not a valid MATLAB struct. \n");
+ }
+
+ // turn MATLAB struct to an XML-based Config object
+ XMLDocument* xml = struct2XML("Algorithm", prhs[1]);
+ Config cfg;
+ cfg.self = xml->getRootNode();
+
+ CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg.self->getAttribute("type"));
+ if (!pAlg) {
+ delete xml;
+ mexErrMsgTxt("Unknown algorithm. \n");
+ return;
+ }
+
+ // create algorithm
+ if (!pAlg->initialize(cfg)) {
+ delete xml;
+ delete pAlg;
+ mexErrMsgTxt("Algorithm not initialized. \n");
+ return;
+ }
+
+ delete xml;
+
+ // store algorithm
+ int iIndex = CAlgorithmManager::getSingleton().store(pAlg);
+
+ // step4: set output
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(iIndex);
+ }
+
+}
+
+#ifdef USE_MATLAB_UNDOCUMENTED
+
+#ifndef USE_PTHREADS_CTRLC
+
+// boost version
+void waitForInterrupt_boost(CAlgorithm* _pAlg)
+{
+ boost::posix_time::milliseconds rel(2000);
+
+ while (!utIsInterruptPending()) {
+
+ // This is an interruption point. If the main thread calls
+ // interrupt(), this thread will terminate here.
+ boost::this_thread::sleep(rel);
+ }
+
+ //mexPrintf("Aborting. Please wait.\n");
+
+ // One last quick check to see if the algorithm already finished
+ boost::this_thread::interruption_point();
+
+ _pAlg->signalAbort();
+}
+
+#else
+
+// pthreads version
+void *waitForInterrupt_pthreads(void *threadid)
+{
+ CAlgorithm* _pAlg = (CAlgorithm*)threadid;
+
+ while (!utIsInterruptPending()) {
+ usleep(50000);
+ pthread_testcancel();
+ }
+
+ //mexPrintf("Aborting. Please wait.\n");
+
+ // One last quick check to see if the algorithm already finished
+ pthread_testcancel();
+
+ _pAlg->signalAbort();
+
+ return 0;
+}
+
+#endif
+#endif
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_algorithm('run', id); or astra_mex_algorithm('iterate', id, iterations);
+ *
+ * Run or do iterations on a certain algorithm.
+ * id: identifier of the algorithm object as stored in the astra-library.
+ * iterations: if the algorithm is iterative, this specifies the number of iterations to perform.
+ */
+void astra_mex_algorithm_run(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iAid = (int)(mxGetScalar(prhs[1]));
+ int iIterations = 0;
+ if (3 <= nrhs) {
+ iIterations = (int)(mxGetScalar(prhs[2]));
+ }
+
+ // step2: get algorithm object
+ CAlgorithm* pAlg = CAlgorithmManager::getSingleton().get(iAid);
+ if (!pAlg) {
+ mexErrMsgTxt("Invalid algorithm ID.\n");
+ return;
+ }
+ if (!pAlg->isInitialized()) {
+ mexErrMsgTxt("Algorithm not initialized. \n");
+ return;
+ }
+
+ // step3: perform actions
+#ifndef USE_MATLAB_UNDOCUMENTED
+
+ pAlg->run(iIterations);
+
+#elif defined(USE_PTHREADS_CTRLC)
+
+ // Start a new thread to watch if the user pressed Ctrl-C
+ pthread_t thread;
+ pthread_create(&thread, 0, waitForInterrupt_pthreads, (void*)pAlg);
+
+ pAlg->run(iIterations);
+
+ // kill the watcher thread in case it's still running
+ pthread_cancel(thread);
+ pthread_join(thread, 0);
+
+#else
+
+ // Start a new thread to watch if the user pressed Ctrl-C
+ boost::thread interruptThread(waitForInterrupt_boost, pAlg);
+
+ pAlg->run(iIterations);
+
+ // kill the watcher thread in case it's still running
+ interruptThread.interrupt();
+ interruptThread.join();
+
+#endif
+}
+//-----------------------------------------------------------------------------------------
+/** astra_mex_algorithm('get_res_norm', id);
+ *
+ * Get the L2-norm of the residual sinogram. Not all algorithms
+ * support this operation.
+ */
+void astra_mex_algorithm_get_res_norm(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iAid = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get algorithm object
+ CAlgorithm* pAlg = CAlgorithmManager::getSingleton().get(iAid);
+ if (!pAlg) {
+ mexErrMsgTxt("Invalid algorithm ID.\n");
+ return;
+ }
+ if (!pAlg->isInitialized()) {
+ mexErrMsgTxt("Algorithm not initialized. \n");
+ return;
+ }
+
+ CReconstructionAlgorithm2D* pAlg2D = dynamic_cast<CReconstructionAlgorithm2D*>(pAlg);
+ CReconstructionAlgorithm3D* pAlg3D = dynamic_cast<CReconstructionAlgorithm3D*>(pAlg);
+
+ float res = 0.0f;
+ bool ok;
+ if (pAlg2D)
+ ok = pAlg2D->getResidualNorm(res);
+ else if (pAlg3D)
+ ok = pAlg3D->getResidualNorm(res);
+ else
+ ok = false;
+
+ if (!ok) {
+ mexErrMsgTxt("Operation not supported.\n");
+ return;
+ }
+
+ plhs[0] = mxCreateDoubleScalar(res);
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_algorithm('delete', id1, id2, ...);
+ *
+ * Delete one or more algorithm objects currently stored in the astra-library.
+ * id1, id2, ... : identifiers of the algorithm objects as stored in the astra-library.
+ */
+void astra_mex_algorithm_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get algorithm ID
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ for (int i = 1; i < nrhs; i++) {
+ int iAid = (int)(mxGetScalar(prhs[i]));
+ CAlgorithmManager::getSingleton().remove(iAid);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_algorithm('clear');
+ *
+ * Delete all algorithm objects currently stored in the astra-library.
+ */
+void astra_mex_algorithm_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ CAlgorithmManager::getSingleton().clear();
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_algorithm('info');
+ *
+ * Print information about all the algorithm objects currently stored in the astra-library.
+ */
+void astra_mex_algorithm_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ mexPrintf("%s", astra::CAlgorithmManager::getSingleton().info().c_str());
+}
+
+//-----------------------------------------------------------------------------------------
+static void printHelp()
+{
+ mexPrintf("Please specify a mode of operation.\n");
+ mexPrintf("Valid modes: create, info, delete, clear, run/iterate, get_res_norm\n");
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * ... = astra_mex_algorithm(mode, ...);
+ */
+void mexFunction(int nlhs, mxArray* plhs[],
+ int nrhs, const mxArray* prhs[])
+{
+ // INPUT: Mode
+ string sMode = "";
+ if (1 <= nrhs) {
+ sMode = mex_util_get_string(prhs[0]);
+ } else {
+ printHelp();
+ return;
+ }
+
+ // SWITCH (MODE)
+ if (sMode == "create") {
+ astra_mex_algorithm_create(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "info") {
+ astra_mex_algorithm_info(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "delete") {
+ astra_mex_algorithm_delete(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "clear") {
+ astra_mex_algorithm_clear(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "run" || sMode == "iterate") {
+ astra_mex_algorithm_run(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "get_res_norm") {
+ astra_mex_algorithm_get_res_norm(nlhs, plhs, nrhs, prhs);
+ } else {
+ printHelp();
+ }
+ return;
+}
diff --git a/matlab/mex/astra_mex_algorithm_vc08.vcproj b/matlab/mex/astra_mex_algorithm_vc08.vcproj
new file mode 100644
index 0000000..baa4c44
--- /dev/null
+++ b/matlab/mex/astra_mex_algorithm_vc08.vcproj
@@ -0,0 +1,593 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="astra_mex_algorithm"
+ ProjectGUID="{056BF7A9-294D-487C-8CC3-BE629077CA94}"
+ RootNamespace="astraMatlab"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32.lib libmex.lib libmx.lib libut.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64.lib libmex.lib libmx.lib libut.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib libut.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="false"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\;"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib libut.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib libut.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\;"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ BrowseInformation="1"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib libut.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib libut.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib libut.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\astra_mex_algorithm_c.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp
new file mode 100644
index 0000000..0068664
--- /dev/null
+++ b/matlab/mex/astra_mex_c.cpp
@@ -0,0 +1,127 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+/** \file astra_mex_c.cpp
+ *
+ * \brief Contains some basic "about" functions.
+ */
+
+#include <mex.h>
+#include "mexHelpFunctions.h"
+
+#include "astra/Globals.h"
+
+using namespace std;
+using namespace astra;
+
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex('credits');
+ *
+ * Print Credits
+ */
+void astra_mex_credits(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ mexPrintf("All Scale Tomographic Reconstruction Antwerp Toolbox (ASTRA-Toolbox) was developed at the University of Antwerp by\n");
+ mexPrintf(" * Prof. dr. Joost Batenburg\n");
+ mexPrintf(" * Andrei Dabravolski\n");
+ mexPrintf(" * Gert Merckx\n");
+ mexPrintf(" * Willem Jan Palenstijn\n");
+ mexPrintf(" * Tom Roelandts\n");
+ mexPrintf(" * Prof. dr. Jan Sijbers\n");
+ mexPrintf(" * dr. Wim van Aarle\n");
+ mexPrintf(" * Sander van der Maar\n");
+ mexPrintf(" * dr. Gert Van Gompel\n");
+}
+
+//-----------------------------------------------------------------------------------------
+/** use_cuda = astra_mex('use_cuda');
+ *
+ * Is CUDA enabled?
+ */
+void astra_mex_use_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(astra::cudaEnabled() ? 1 : 0);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** version_number = astra_mex('version');
+ *
+ * Fetch the version number of the toolbox.
+ */
+void astra_mex_version(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(astra::getVersion());
+ } else {
+ mexPrintf("astra toolbox version %s\n", astra::getVersionString());
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+
+static void printHelp()
+{
+ mexPrintf("Please specify a mode of operation.\n");
+ mexPrintf(" Valid modes: version, use_cuda, credits\n");
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * ... = astra_mex(type,...);
+ */
+void mexFunction(int nlhs, mxArray* plhs[],
+ int nrhs, const mxArray* prhs[])
+{
+
+ // INPUT0: Mode
+ string sMode = "";
+ if (1 <= nrhs) {
+ sMode = mex_util_get_string(prhs[0]);
+ } else {
+ printHelp();
+ return;
+ }
+
+ // SWITCH (MODE)
+ if (sMode == std::string("version")) {
+ astra_mex_version(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("use_cuda")) {
+ astra_mex_use_cuda(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("credits")) {
+ astra_mex_credits(nlhs, plhs, nrhs, prhs);
+ } else {
+ printHelp();
+ }
+
+ return;
+}
+
+
diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp
new file mode 100644
index 0000000..99fb38e
--- /dev/null
+++ b/matlab/mex/astra_mex_data2d_c.cpp
@@ -0,0 +1,667 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+/** \file astra_mex_data2d_c.cpp
+ *
+ * \brief Creates, manages and manipulates 2D volume and projection data objects.
+ */
+#include <mex.h>
+#include "mexHelpFunctions.h"
+
+#include <list>
+
+#include "astra/Globals.h"
+
+#include "astra/AstraObjectManager.h"
+
+#include "astra/Float32ProjectionData2D.h"
+#include "astra/Float32VolumeData2D.h"
+#include "astra/SparseMatrixProjectionGeometry2D.h"
+#include "astra/FanFlatProjectionGeometry2D.h"
+#include "astra/FanFlatVecProjectionGeometry2D.h"
+
+using namespace std;
+using namespace astra;
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_data2d('delete', id1, id2, ...);
+ *
+ * Delete one or more data objects currently stored in the astra-library.
+ * id1, id2, ... : identifiers of the 2d data objects as stored in the astra-library.
+ */
+void astra_mex_data2d_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: read input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ // step2: delete all specified data objects
+ for (int i = 1; i < nrhs; i++) {
+ int iDataID = (int)(mxGetScalar(prhs[i]));
+ CData2DManager::getSingleton().remove(iDataID);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_data2d('clear');
+ *
+ * Delete all data objects currently stored in the astra-library.
+ */
+void astra_mex_data2d_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ CData2DManager::getSingleton().clear();
+}
+
+//-----------------------------------------------------------------------------------------
+/** id = astra_mex_data2d('create', datatype, geometry, data);
+ *
+ * Create a new data 2d object in the astra-library.
+ * type: '-vol' for volume data, '-sino' for projection data
+ * geom: MATLAB struct with the geometry for the data
+ * data: Optional. Can be either a MATLAB matrix containing the data. In that case the dimensions
+ * should match that of the geometry of the object. It can also be a single value, in which case
+ * the entire data will be set to that value. If this isn't specified all values are set to 0.
+ * id: identifier of the 2d data object as it is now stored in the astra-library.
+ */
+void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[])
+{
+ // step1: get datatype
+ if (nrhs < 3) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ string sDataType = mex_util_get_string(prhs[1]);
+ CFloat32Data2D* pDataObject2D = NULL;
+
+ if (nrhs >= 4 && !(mex_is_scalar(prhs[3])|| mxIsDouble(prhs[3]) || mxIsLogical(prhs[3]) || mxIsSingle(prhs[3]) )) {
+ mexErrMsgTxt("Data must be single, double or logical.");
+ return;
+ }
+
+ // SWITCH DataType
+ if (sDataType == "-vol") {
+ // Read geometry
+ if (!mxIsStruct(prhs[2])) {
+ mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
+ }
+ XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]);
+ if (!xml)
+ return;
+ Config cfg;
+ cfg.self = xml->getRootNode();
+ CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D();
+ if (!pGeometry->initialize(cfg)) {
+ mexErrMsgTxt("Geometry class not initialized. \n");
+ delete xml;
+ delete pGeometry;
+ return;
+ }
+ // If data is specified, check dimensions
+ if (nrhs >= 4 && !mex_is_scalar(prhs[3])) {
+ if (pGeometry->getGridColCount() != mxGetN(prhs[3]) || pGeometry->getGridRowCount() != mxGetM(prhs[3])) {
+ mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
+ delete xml;
+ delete pGeometry;
+ return;
+ }
+ }
+ // Initialize data object
+ pDataObject2D = new CFloat32VolumeData2D(pGeometry);
+ delete pGeometry;
+ delete xml;
+ }
+ else if (sDataType == "-sino") {
+ // Read geometry
+ if (!mxIsStruct(prhs[2])) {
+ mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
+ }
+ XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]);
+ if (!xml)
+ return;
+ Config cfg;
+ cfg.self = xml->getRootNode();
+ // FIXME: Change how the base class is created. (This is duplicated
+ // in 'change_geometry' and Projector2D.cpp.)
+ std::string type = cfg.self->getAttribute("type");
+ CProjectionGeometry2D* pGeometry;
+ if (type == "sparse_matrix") {
+ pGeometry = new CSparseMatrixProjectionGeometry2D();
+ } else if (type == "fanflat") {
+ //CFanFlatProjectionGeometry2D* pFanFlatProjectionGeometry = new CFanFlatProjectionGeometry2D();
+ //pFanFlatProjectionGeometry->initialize(Config(node));
+ //m_pProjectionGeometry = pFanFlatProjectionGeometry;
+ pGeometry = new CFanFlatProjectionGeometry2D();
+ } else if (type == "fanflat_vec") {
+ pGeometry = new CFanFlatVecProjectionGeometry2D();
+ } else {
+ pGeometry = new CParallelProjectionGeometry2D();
+ }
+ if (!pGeometry->initialize(cfg)) {
+ mexErrMsgTxt("Geometry class not initialized. \n");
+ delete pGeometry;
+ delete xml;
+ return;
+ }
+ // If data is specified, check dimensions
+ if (nrhs >= 4 && !mex_is_scalar(prhs[3])) {
+ if (pGeometry->getDetectorCount() != mxGetN(prhs[3]) || pGeometry->getProjectionAngleCount() != mxGetM(prhs[3])) {
+ mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
+ delete pGeometry;
+ delete xml;
+ return;
+ }
+ }
+ // Initialize data object
+ pDataObject2D = new CFloat32ProjectionData2D(pGeometry);
+ delete pGeometry;
+ delete xml;
+ }
+ else {
+ mexErrMsgTxt("Invalid datatype. Please specify '-vol' or '-sino'. \n");
+ return;
+ }
+
+ // Check initialization
+ if (!pDataObject2D->isInitialized()) {
+ mexErrMsgTxt("Couldn't initialize data object.\n");
+ delete pDataObject2D;
+ return;
+ }
+
+ // Store data
+ if (nrhs == 3) {
+ for (int i = 0; i < pDataObject2D->getSize(); ++i) {
+ pDataObject2D->getData()[i] = 0.0f;
+ }
+ }
+
+ // Store data
+ if (nrhs >= 4) {
+ // fill with scalar value
+ if (mex_is_scalar(prhs[3])) {
+ float32 fValue = (float32)mxGetScalar(prhs[3]);
+ for (int i = 0; i < pDataObject2D->getSize(); ++i) {
+ pDataObject2D->getData()[i] = fValue;
+ }
+ }
+ // fill with array value
+ else {
+ const mwSize* dims = mxGetDimensions(prhs[3]);
+ // Check Data dimensions
+ if (pDataObject2D->getWidth() != mxGetN(prhs[3]) || pDataObject2D->getHeight() != mxGetM(prhs[3])) {
+ mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
+ return;
+ }
+
+ // logical data
+ if (mxIsLogical(prhs[3])) {
+ bool* pbMatlabData = mxGetLogicals(prhs[3]);
+ int i = 0;
+ int col, row;
+ for (col = 0; col < dims[1]; ++col) {
+ for (row = 0; row < dims[0]; ++row) {
+ pDataObject2D->getData2D()[row][col] = (float32)pbMatlabData[i];
+ ++i;
+ }
+ }
+ // double data
+ } else if (mxIsDouble(prhs[3])) {
+ double* pdMatlabData = mxGetPr(prhs[3]);
+ int i = 0;
+ int col, row;
+ for (col = 0; col < dims[1]; ++col) {
+ for (row = 0; row < dims[0]; ++row) {
+ pDataObject2D->getData2D()[row][col] = pdMatlabData[i];
+ ++i;
+ }
+ }
+ // single data
+ } else if (mxIsSingle(prhs[3])) {
+ const float* pfMatlabData = (const float *)mxGetData(prhs[3]);
+ int i = 0;
+ int col, row;
+ for (col = 0; col < dims[1]; ++col) {
+ for (row = 0; row < dims[0]; ++row) {
+ pDataObject2D->getData2D()[row][col] = pfMatlabData[i];
+ ++i;
+ }
+ }
+ } else {
+ ASTRA_ASSERT(false);
+ }
+ }
+ }
+
+ // step4: store data object
+ int iIndex = CData2DManager::getSingleton().store(pDataObject2D);
+
+ // step5: return data id
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(iIndex);
+ }
+
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_data2d('store', id, data);
+ *
+ * Store data in an existing astra 2d dataobject with a MATLAB matrix or with a scalar value.
+ * id: identifier of the 2d data object as stored in the astra-library.
+ * data: can be either a MATLAB matrix containing the data. In that case the dimensions should match that of the geometry of the object. It can also be a single value, in which case the entire data will be set to that value.
+ */
+void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: input
+ if (nrhs < 3) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ if (!mxIsDouble(prhs[1])) {
+ mexErrMsgTxt("Identifier should be a scalar value. \n");
+ return;
+ }
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+
+ if (!(mex_is_scalar(prhs[2]) || mxIsDouble(prhs[2]) || mxIsLogical(prhs[2]) || mxIsSingle(prhs[2]))) {
+ mexErrMsgTxt("Data must be single, double or logical.");
+ return;
+ }
+
+ // step2: get data object
+ CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID);
+ if (!pDataObject || !pDataObject->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ // step3: insert data
+ // fill with scalar value
+ if (mex_is_scalar(prhs[2])) {
+ float32 fValue = (float32)mxGetScalar(prhs[2]);
+ for (int i = 0; i < pDataObject->getSize(); ++i) {
+ pDataObject->getData()[i] = fValue;
+ }
+ } else {
+ // Check Data dimensions
+ if (pDataObject->getWidth() != mxGetN(prhs[2]) || pDataObject->getHeight() != mxGetM(prhs[2])) {
+ mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
+ return;
+ }
+ const mwSize* dims = mxGetDimensions(prhs[2]);
+
+ // logical data
+ if (mxIsLogical(prhs[2])) {
+ bool* pbMatlabData = mxGetLogicals(prhs[2]);
+ int i = 0;
+ int col, row;
+ for (col = 0; col < dims[1]; ++col) {
+ for (row = 0; row < dims[0]; ++row) {
+ pDataObject->getData2D()[row][col] = (float32)pbMatlabData[i];
+ ++i;
+ }
+ }
+ // double data
+ } else if (mxIsDouble(prhs[2])) {
+ double* pdMatlabData = mxGetPr(prhs[2]);
+ int i = 0;
+ int col, row;
+ for (col = 0; col < dims[1]; ++col) {
+ for (row = 0; row < dims[0]; ++row) {
+ pDataObject->getData2D()[row][col] = pdMatlabData[i];
+ ++i;
+ }
+ }
+ // single data
+ } else if (mxIsSingle(prhs[2])) {
+ const float* pfMatlabData = (const float *)mxGetData(prhs[2]);
+ int i = 0;
+ int col, row;
+ for (col = 0; col < dims[1]; ++col) {
+ for (row = 0; row < dims[0]; ++row) {
+ pDataObject->getData2D()[row][col] = pfMatlabData[i];
+ ++i;
+ }
+ }
+ } else {
+ ASTRA_ASSERT(false);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** geom = astra_mex_data2d('get_geometry', id);
+ *
+ * Fetch the geometry of a 2d data object stored in the astra-library.
+ * id: identifier of the 2d data object as stored in the astra-library.
+ * geom: MATLAB-struct containing information about the used geometry.
+ */
+void astra_mex_data2d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ if (!mxIsDouble(prhs[1])) {
+ mexErrMsgTxt("Identifier should be a scalar value. \n");
+ return;
+ }
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get data object
+ CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID);
+ if (!pDataObject || !pDataObject->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ // create output
+ if (1 <= nlhs) {
+ if (pDataObject->getType() == CFloat32Data2D::PROJECTION) {
+ CFloat32ProjectionData2D* pDataObject2 = dynamic_cast<CFloat32ProjectionData2D*>(pDataObject);
+ plhs[0] = createProjectionGeometryStruct(pDataObject2->getGeometry());
+ }
+ else if (pDataObject->getType() == CFloat32Data2D::VOLUME) {
+ CFloat32VolumeData2D* pDataObject2 = dynamic_cast<CFloat32VolumeData2D*>(pDataObject);
+ plhs[0] = createVolumeGeometryStruct(pDataObject2->getGeometry());
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_data2d('change_geometry', id, geom);
+ *
+ * Change the associated geometry of a 2d data object (volume or sinogram)
+ * id: identifier of the 2d data object as stored in the astra-library.
+ * geom: the new geometry struct, as created by astra_create_vol/proj_geom
+ */
+void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: check input
+ if (nrhs < 3) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ if (!mxIsDouble(prhs[1])) {
+ mexErrMsgTxt("Identifier should be a scalar value. \n");
+ return;
+ }
+
+ // step2: get data object
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+ CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID);
+ if (!pDataObject || !pDataObject->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ CFloat32ProjectionData2D* pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(pDataObject);
+
+ if (pSinogram) {
+ // Projection data
+
+ // Read geometry
+ if (!mxIsStruct(prhs[2])) {
+ mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
+ }
+ XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]);
+ Config cfg;
+ cfg.self = xml->getRootNode();
+ // FIXME: Change how the base class is created. (This is duplicated
+ // in 'create' and Projector2D.cpp.)
+ std::string type = cfg.self->getAttribute("type");
+ CProjectionGeometry2D* pGeometry;
+ if (type == "sparse_matrix") {
+ pGeometry = new CSparseMatrixProjectionGeometry2D();
+ } else if (type == "fanflat") {
+ //CFanFlatProjectionGeometry2D* pFanFlatProjectionGeometry = new CFanFlatProjectionGeometry2D();
+ //pFanFlatProjectionGeometry->initialize(Config(node));
+ //m_pProjectionGeometry = pFanFlatProjectionGeometry;
+ pGeometry = new CFanFlatProjectionGeometry2D();
+ } else if (type == "fanflat_vec") {
+ pGeometry = new CFanFlatVecProjectionGeometry2D();
+ } else {
+ pGeometry = new CParallelProjectionGeometry2D();
+ }
+ if (!pGeometry->initialize(cfg)) {
+ mexErrMsgTxt("Geometry class not initialized. \n");
+ delete pGeometry;
+ delete xml;
+ return;
+ }
+ // If data is specified, check dimensions
+ if (pGeometry->getDetectorCount() != pSinogram->getDetectorCount() || pGeometry->getProjectionAngleCount() != pSinogram->getAngleCount()) {
+ mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
+ delete pGeometry;
+ delete xml;
+ return;
+ }
+
+ // If ok, change geometry
+ pSinogram->changeGeometry(pGeometry);
+ delete pGeometry;
+ delete xml;
+
+ return;
+ }
+
+ CFloat32VolumeData2D* pVolume = dynamic_cast<CFloat32VolumeData2D*>(pDataObject);
+
+ if (pVolume) {
+ // Volume data
+
+ // Read geometry
+ if (!mxIsStruct(prhs[2])) {
+ mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
+ }
+ XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]);
+ Config cfg;
+ cfg.self = xml->getRootNode();
+ CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D();
+ if (!pGeometry->initialize(cfg)) {
+ mexErrMsgTxt("Geometry class not initialized. \n");
+ delete xml;
+ delete pGeometry;
+ return;
+ }
+ // If data is specified, check dimensions
+ if (pGeometry->getGridColCount() != pVolume->getWidth() || pGeometry->getGridRowCount() != pVolume->getHeight()) {
+ mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
+ delete xml;
+ delete pGeometry;
+ return;
+ }
+
+ // If ok, change geometry
+ pVolume->changeGeometry(pGeometry);
+ delete xml;
+ delete pGeometry;
+
+ }
+
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+}
+
+//-----------------------------------------------------------------------------------------
+/** data = astra_mex_data2d('get', id);
+ *
+ * Fetch data from the astra-library to a MATLAB matrix.
+ * id: identifier of the 2d data object as stored in the astra-library.
+ * data: MATLAB data
+ */
+void astra_mex_data2d_get(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: check input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ if (!mxIsDouble(prhs[1])) {
+ mexErrMsgTxt("Identifier should be a scalar value. \n");
+ return;
+ }
+
+ // step2: get data object
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+ CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID);
+ if (!pDataObject || !pDataObject->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ // create output
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleMatrix(pDataObject->getHeight(), // # rows
+ pDataObject->getWidth(), // # cols
+ mxREAL); // datatype 64-bits
+ double* out = mxGetPr(plhs[0]);
+ int i = 0;
+ int row, col;
+ for (col = 0; col < pDataObject->getWidth(); ++col) {
+ for (row = 0; row < pDataObject->getHeight(); ++row) {
+ out[i] = pDataObject->getData2D()[row][col];
+ ++i;
+ }
+ }
+ }
+
+}
+
+//-----------------------------------------------------------------------------------------
+/** data = astra_mex_data2d('get_single', id);
+ *
+ * Fetch data from the astra-library to a MATLAB matrix.
+ * id: identifier of the 2d data object as stored in the astra-library.
+ * data: MATLAB data
+ */
+void astra_mex_data2d_get_single(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: check input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ if (!mxIsDouble(prhs[1])) {
+ mexErrMsgTxt("Identifier should be a scalar value. \n");
+ return;
+ }
+
+ // step2: get data object
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+ CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID);
+ if (!pDataObject || !pDataObject->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ // create output
+ if (1 <= nlhs) {
+ mwSize dims[2];
+ dims[0] = pDataObject->getHeight();
+ dims[1] = pDataObject->getWidth();
+ plhs[0] = mxCreateNumericArray(2, dims, mxSINGLE_CLASS, mxREAL);
+ float* out = (float *)mxGetData(plhs[0]);
+ int i = 0;
+ int row, col;
+ for (col = 0; col < pDataObject->getWidth(); ++col) {
+ for (row = 0; row < pDataObject->getHeight(); ++row) {
+ out[i] = pDataObject->getData2D()[row][col];
+ ++i;
+ }
+ }
+ }
+
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_data2d('info');
+ *
+ * Print information about all the 2d data objects currently stored in the astra-library.
+ */
+void astra_mex_data2d_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ mexPrintf("%s", astra::CData2DManager::getSingleton().info().c_str());
+}
+
+//-----------------------------------------------------------------------------------------
+
+static void printHelp()
+{
+ mexPrintf("Please specify a mode of operation.\n");
+ mexPrintf("Valid modes: get, get_single, delete, clear, set/store, create, get_geometry, change_geometry, info\n");
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * ... = astra_mex_data2d(type,...);
+ */
+void mexFunction(int nlhs, mxArray* plhs[],
+ int nrhs, const mxArray* prhs[])
+{
+
+ // INPUT0: Mode
+ string sMode = "";
+ if (1 <= nrhs) {
+ sMode = mex_util_get_string(prhs[0]);
+ } else {
+ printHelp();
+ return;
+ }
+
+ // SWITCH (MODE)
+ if (sMode == std::string("get")) {
+ astra_mex_data2d_get(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("get_single")) {
+ astra_mex_data2d_get_single(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("delete")) {
+ astra_mex_data2d_delete(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "clear") {
+ astra_mex_data2d_clear(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("store") ||
+ sMode == std::string("set")) {
+ astra_mex_data2d_store(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("create")) {
+ astra_mex_data2d_create(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("get_geometry")) {
+ astra_mex_data2d_get_geometry(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("change_geometry")) {
+ astra_mex_data2d_change_geometry(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("info")) {
+ astra_mex_data2d_info(nlhs, plhs, nrhs, prhs);
+ } else {
+ printHelp();
+ }
+
+ return;
+}
+
+
diff --git a/matlab/mex/astra_mex_data2d_vc08.vcproj b/matlab/mex/astra_mex_data2d_vc08.vcproj
new file mode 100644
index 0000000..8f1fc13
--- /dev/null
+++ b/matlab/mex/astra_mex_data2d_vc08.vcproj
@@ -0,0 +1,591 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="astra_mex_data2d"
+ ProjectGUID="{E4092269-B19C-46F7-A84E-4F146CC70E44}"
+ RootNamespace="astraMatlab"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\;"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;$(CUDA_INC_PATH)&quot;;$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ BrowseInformation="1"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\astra_mex_data2d_c.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp
new file mode 100644
index 0000000..1af8844
--- /dev/null
+++ b/matlab/mex/astra_mex_data3d_c.cpp
@@ -0,0 +1,1036 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+/** \file astra_mex_data3d_c.cpp
+ *
+ * \brief Creates, manages and manipulates 3D volume and projection data objects.
+ */
+#include <mex.h>
+#include "mexHelpFunctions.h"
+
+#include <list>
+
+#include "astra/Globals.h"
+
+#include "astra/AstraObjectManager.h"
+
+#include "astra/Float32ProjectionData2D.h"
+#include "astra/Float32VolumeData2D.h"
+#include "astra/Float32ProjectionData3D.h"
+#include "astra/Float32ProjectionData3DMemory.h"
+#include "astra/Float32VolumeData3D.h"
+#include "astra/Float32VolumeData3DMemory.h"
+#include "astra/ParallelProjectionGeometry3D.h"
+#include "astra/ParallelVecProjectionGeometry3D.h"
+#include "astra/ConeProjectionGeometry3D.h"
+#include "astra/ConeVecProjectionGeometry3D.h"
+
+using namespace std;
+using namespace astra;
+
+
+
+//-----------------------------------------------------------------------------------------
+/**
+ * id = astra_mex_io_data('create', datatype, geometry, data);
+ * datatype: ['-vol','-sino','-sinocone']
+ */
+void astra_mex_data3d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[])
+{
+ // step1: get datatype
+ if (nrhs < 3) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ string sDataType = mex_util_get_string(prhs[1]);
+ CFloat32Data3DMemory* pDataObject3D = NULL;
+
+ if (nrhs >= 4 && !(mex_is_scalar(prhs[3]) || mxIsDouble(prhs[3]) || mxIsSingle(prhs[3]))) {
+ mexErrMsgTxt("Data must be single or double.");
+ return;
+ }
+
+ mwSize dims[3];
+
+ // SWITCH DataType
+ if (sDataType == "-vol") {
+
+ // Read geometry
+ if (!mxIsStruct(prhs[2])) {
+ mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
+ }
+ Config cfg;
+ XMLDocument* xml = struct2XML("VolumeGeometry", prhs[2]);
+ if (!xml)
+ return;
+ cfg.self = xml->getRootNode();
+ CVolumeGeometry3D* pGeometry = new CVolumeGeometry3D();
+ if (!pGeometry->initialize(cfg)) {
+ mexErrMsgTxt("Geometry class not initialized. \n");
+ delete pGeometry;
+ delete xml;
+ return;
+ }
+ delete xml;
+
+ // If data is specified, check dimensions
+ if (nrhs >= 4 && !mex_is_scalar(prhs[3])) {
+ get3DMatrixDims(prhs[3], dims);
+ if (pGeometry->getGridColCount() != dims[0] || pGeometry->getGridRowCount() != dims[1] || pGeometry->getGridSliceCount() != dims[2]) {
+ mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
+ delete pGeometry;
+ return;
+ }
+ }
+
+ // Initialize data object
+ pDataObject3D = new CFloat32VolumeData3DMemory(pGeometry);
+ delete pGeometry;
+ }
+
+ else if (sDataType == "-sino" || sDataType == "-proj3d") {
+
+ // Read geometry
+ if (!mxIsStruct(prhs[2])) {
+ mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
+ }
+ XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]);
+ if (!xml)
+ return;
+ Config cfg;
+ cfg.self = xml->getRootNode();
+
+ // FIXME: Change how the base class is created. (This is duplicated
+ // in Projector2D.cpp.)
+ std::string type = cfg.self->getAttribute("type");
+ CProjectionGeometry3D* pGeometry = 0;
+ if (type == "parallel3d") {
+ pGeometry = new CParallelProjectionGeometry3D();
+ } else if (type == "parallel3d_vec") {
+ pGeometry = new CParallelVecProjectionGeometry3D();
+ } else if (type == "cone") {
+ pGeometry = new CConeProjectionGeometry3D();
+ } else if (type == "cone_vec") {
+ pGeometry = new CConeVecProjectionGeometry3D();
+ } else {
+ mexErrMsgTxt("Invalid geometry type.\n");
+ return;
+ }
+
+ if (!pGeometry->initialize(cfg)) {
+ mexErrMsgTxt("Geometry class not initialized. \n");
+ delete pGeometry;
+ delete xml;
+ return;
+ }
+ delete xml;
+
+ // If data is specified, check dimensions
+ if (nrhs >= 4 && !mex_is_scalar(prhs[3])) {
+ get3DMatrixDims(prhs[3], dims);
+ if (pGeometry->getDetectorColCount() != dims[0] || pGeometry->getProjectionCount() != dims[1] || pGeometry->getDetectorRowCount() != dims[2]) {
+ mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
+ delete pGeometry;
+ return;
+ }
+ }
+
+ // Initialize data object
+ pDataObject3D = new CFloat32ProjectionData3DMemory(pGeometry);
+ }
+
+ else if (sDataType == "-sinocone") {
+ // Read geometry
+ if (!mxIsStruct(prhs[2])) {
+ mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
+ }
+ XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]);
+ if (!xml)
+ return;
+ Config cfg;
+ cfg.self = xml->getRootNode();
+ CConeProjectionGeometry3D* pGeometry = new CConeProjectionGeometry3D();
+ if (!pGeometry->initialize(cfg)) {
+ mexErrMsgTxt("Geometry class not initialized. \n");
+ delete xml;
+ delete pGeometry;
+ return;
+ }
+ delete xml;
+ // If data is specified, check dimensions
+ if (nrhs >= 4 && !mex_is_scalar(prhs[3])) {
+ get3DMatrixDims(prhs[3], dims);
+ if (pGeometry->getDetectorRowCount() != dims[2] || pGeometry->getProjectionCount() != dims[1] || pGeometry->getDetectorColCount() != dims[0]) {
+ mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
+ delete pGeometry;
+ return;
+ }
+ }
+ // Initialize data object
+ pDataObject3D = new CFloat32ProjectionData3DMemory(pGeometry);
+ delete pGeometry;
+ }
+ else {
+ mexErrMsgTxt("Invalid datatype. Please specify '-vol' or '-proj3d'. \n");
+ return;
+ }
+
+ // Check initialization
+ if (!pDataObject3D->isInitialized()) {
+ mexErrMsgTxt("Couldn't initialize data object.\n");
+ delete pDataObject3D;
+ return;
+ }
+
+ // Store data
+
+ // fill with scalar value
+ if (nrhs < 4 || mex_is_scalar(prhs[3])) {
+ float32 fValue = 0.0f;
+ if (nrhs >= 4)
+ fValue = (float32)mxGetScalar(prhs[3]);
+ for (int i = 0; i < pDataObject3D->getSize(); ++i) {
+ pDataObject3D->getData()[i] = fValue;
+ }
+ }
+ // fill with array value
+ else if (mxIsDouble(prhs[3])) {
+ double* pdMatlabData = mxGetPr(prhs[3]);
+ int i = 0;
+ int col, row, slice;
+ for (slice = 0; slice < dims[2]; ++slice) {
+ for (row = 0; row < dims[1]; ++row) {
+ for (col = 0; col < dims[0]; ++col) {
+ // TODO: Benchmark and remove triple indexing?
+ pDataObject3D->getData3D()[slice][row][col] = pdMatlabData[i];
+ ++i;
+ }
+ }
+ }
+ }
+ else if (mxIsSingle(prhs[3])) {
+ const float* pfMatlabData = (const float*)mxGetData(prhs[3]);
+ int i = 0;
+ int col, row, slice;
+ for (slice = 0; slice < dims[2]; ++slice) {
+ for (row = 0; row < dims[1]; ++row) {
+ for (col = 0; col < dims[0]; ++col) {
+ // TODO: Benchmark and remove triple indexing?
+ pDataObject3D->getData3D()[slice][row][col] = pfMatlabData[i];
+ ++i;
+ }
+ }
+ }
+ }
+ pDataObject3D->updateStatistics();
+
+ // step4: store data object
+ int iIndex = CData3DManager::getSingleton().store(pDataObject3D);
+
+ // step5: return data id
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(iIndex);
+ }
+
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * [id] = astra_mex_io_data('create_cache', config);
+ */
+void astra_mex_data3d_create_cache(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+// if (nrhs < 2) {
+// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+// return;
+// }
+//
+// if (!mxIsStruct(prhs[1])) {
+// mexErrMsgTxt("Argument 1 not a valid MATLAB struct. \n");
+// }
+//
+// // turn MATLAB struct to an XML-based Config object
+// XMLDocument* xml = struct2XML("Data3D", prhs[1]);
+// Config cfg;
+// cfg.self = xml->getRootNode();
+//
+// // create dataobject
+// string sType = cfg.self->getAttribute("type");
+// int iIndex;
+// if (sType == "ProjectionCached") {
+// CFloat32ProjectionData3DCached* pData = new CFloat32ProjectionData3DCached(cfg);
+// iIndex = CData3DManager::getSingleton().store(pData);
+// }
+//// else if (sType == "VolumeCached") {
+//// CFloat32VolumeData3DCached* pData = new CFloat32VolumeData3DCached(cfg);
+//// pData->initialize(cfg);
+//// iIndex = CData3DManager::getSingleton().store(pData);
+//// }
+//
+// // step4: set output
+// if (1 <= nlhs) {
+// plhs[0] = mxCreateDoubleScalar(iIndex);
+// }
+
+}
+
+
+//-----------------------------------------------------------------------------------------
+/**
+ * data = astra_mex_data3d('get', id);
+ *
+ * Fetch data from the astra-library to a MATLAB matrix.
+ * id: identifier of the 3d data object as stored in the astra-library.
+ * data: MATLAB data
+
+ */
+void astra_mex_data3d_get(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get data object
+ CFloat32Data3DMemory* pDataObject = dynamic_cast<CFloat32Data3DMemory*>(astra::CData3DManager::getSingleton().get(iDataID));
+ if (!pDataObject || !pDataObject->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ // create output
+ if (1 <= nlhs) {
+ mwSize dims[3];
+ dims[0] = pDataObject->getWidth();
+ dims[1] = pDataObject->getHeight();
+ dims[2] = pDataObject->getDepth();
+
+ plhs[0] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL);
+ double* out = mxGetPr(plhs[0]);
+
+ int i = 0;
+ for (int slice = 0; slice < pDataObject->getDepth(); slice++) {
+ for (int row = 0; row < pDataObject->getHeight(); row++) {
+ for (int col = 0; col < pDataObject->getWidth(); col++) {
+ // TODO: Benchmark and remove triple indexing?
+ out[i] = pDataObject->getData3D()[slice][row][col];
+ ++i;
+ }
+ }
+ }
+ }
+
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * data = astra_mex_data3d('get_single', id);
+ *
+ * Fetch data from the astra-library to a MATLAB matrix.
+ * id: identifier of the 3d data object as stored in the astra-library.
+ * data: MATLAB data
+
+ */
+void astra_mex_data3d_get_single(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get data object
+ CFloat32Data3DMemory* pDataObject = dynamic_cast<CFloat32Data3DMemory*>(astra::CData3DManager::getSingleton().get(iDataID));
+ if (!pDataObject || !pDataObject->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ // create output
+ if (1 <= nlhs) {
+ mwSize dims[3];
+ dims[0] = pDataObject->getWidth();
+ dims[1] = pDataObject->getHeight();
+ dims[2] = pDataObject->getDepth();
+
+ plhs[0] = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL);
+ float* out = (float *)mxGetData(plhs[0]);
+
+ int i = 0;
+ for (int slice = 0; slice < pDataObject->getDepth(); slice++) {
+ for (int row = 0; row < pDataObject->getHeight(); row++) {
+ for (int col = 0; col < pDataObject->getWidth(); col++) {
+ // TODO: Benchmark and remove triple indexing?
+ out[i] = pDataObject->getData3D()[slice][row][col];
+ ++i;
+ }
+ }
+ }
+ }
+
+}
+
+
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_data3d('store', id, data);
+ *
+ * Store MATLAB matrix data in the astra-library.
+ * id: identifier of the 3d data object as stored in the astra-library.
+ * data: MATLAB data
+
+ */
+void astra_mex_data3d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: input
+ if (nrhs < 3) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get data object
+ CFloat32Data3DMemory* pDataObject = dynamic_cast<CFloat32Data3DMemory*>(astra::CData3DManager::getSingleton().get(iDataID));
+ if (!pDataObject || !pDataObject->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ if (!(mex_is_scalar(prhs[2]) || mxIsDouble(prhs[2]) || mxIsSingle(prhs[2]))) {
+ mexErrMsgTxt("Data must be single or double.");
+ return;
+ }
+
+ // fill with scalar value
+ if (mex_is_scalar(prhs[2])) {
+ float32 fValue = (float32)mxGetScalar(prhs[2]);
+ for (int i = 0; i < pDataObject->getSize(); ++i) {
+ pDataObject->getData()[i] = fValue;
+ }
+ }
+ // fill with array value
+ else if (mxIsDouble(prhs[2])) {
+ mwSize dims[3];
+ get3DMatrixDims(prhs[2], dims);
+ if (dims[0] != pDataObject->getWidth() || dims[1] != pDataObject->getHeight() || dims[2] != pDataObject->getDepth()) {
+ mexErrMsgTxt("Data object dimensions don't match.\n");
+ return;
+
+ }
+ double* pdMatlabData = mxGetPr(prhs[2]);
+ int i = 0;
+ int col, row, slice;
+ for (slice = 0; slice < dims[2]; ++slice) {
+ for (row = 0; row < dims[1]; ++row) {
+ for (col = 0; col < dims[0]; ++col) {
+ // TODO: Benchmark and remove triple indexing?
+ pDataObject->getData3D()[slice][row][col] = pdMatlabData[i];
+ ++i;
+ }
+ }
+ }
+ }
+ else if (mxIsSingle(prhs[2])) {
+ mwSize dims[3];
+ get3DMatrixDims(prhs[2], dims);
+ if (dims[0] != pDataObject->getWidth() || dims[1] != pDataObject->getHeight() || dims[2] != pDataObject->getDepth()) {
+ mexErrMsgTxt("Data object dimensions don't match.\n");
+ return;
+
+ }
+ const float* pfMatlabData = (const float *)mxGetData(prhs[2]);
+ int i = 0;
+ int col, row, slice;
+ for (slice = 0; slice < dims[2]; ++slice) {
+ for (row = 0; row < dims[1]; ++row) {
+ for (col = 0; col < dims[0]; ++col) {
+ // TODO: Benchmark and remove triple indexing?
+ pDataObject->getData3D()[slice][row][col] = pfMatlabData[i];
+ ++i;
+ }
+ }
+ }
+ }
+ pDataObject->updateStatistics();
+}
+
+
+//-----------------------------------------------------------------------------------------
+/**
+ * [id] = astra_mex_io_data('fetch_slice', id, slicenr);
+ */
+void astra_mex_data3d_fetch_slice_z(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+// // step1: get input
+// if (nrhs < 3) {
+// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+// return;
+// }
+// int iDid = (int)(mxGetScalar(prhs[1]));
+// int iSliceNr = (int)(mxGetScalar(prhs[2]));
+//
+// // Get data object
+// CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+// if (!pData) {
+// mexErrMsgTxt("DataObject not valid. \n");
+// return;
+// }
+//
+// CFloat32Data2D* res = NULL;
+// // Projection Data
+// if (pData->getType() == CFloat32Data3D::PROJECTION) {
+// CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData);
+//// res = pData2->fetchSlice(iSliceNr);
+// }
+// // Volume Data
+// else if (pData->getType() == CFloat32Data3D::VOLUME) {
+// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
+//// res = pData2->fetchSliceZ(iSliceNr);
+// }
+// // Error
+// else {
+// mexErrMsgTxt("DataObject not valid. \n");
+// return;
+// }
+//
+// // store data
+// int iIndex = CData2DManager::getSingleton().store(res);
+//
+// // step4: set output
+// if (1 <= nlhs) {
+// plhs[0] = mxCreateDoubleScalar(iIndex);
+// }
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_io_data('returnSlice', id, slicenr);
+ */
+void astra_mex_data3d_return_slice_z(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+// // step1: get input
+// if (nrhs < 3) {
+// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+// return;
+// }
+// int iDid = (int)(mxGetScalar(prhs[1]));
+// int iSliceNr = (int)(mxGetScalar(prhs[2]));
+//
+// // Get data object
+// CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+// if (!pData) {
+// mexErrMsgTxt("DataObject not valid. \n");
+// return;
+// }
+//
+// // Projection Data
+// if (pData->getType() == CFloat32Data3D::PROJECTION) {
+// CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData);
+//// TODO: think about returning slices
+//// pData2->returnSlice(iSliceNr);
+// }
+// // Volume Data
+// else if (pData->getType() == CFloat32Data3D::VOLUME) {
+// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
+//// TODO: think about returning slices
+//// pData2->returnSliceZ(iSliceNr);
+// }
+// // Error
+// else {
+// mexErrMsgTxt("DataObject not valid. \n");
+// return;
+// }
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * [id] = astra_mex_io_data('fetch_projection', id, slicenr);
+ */
+void astra_mex_data3d_fetch_projection(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ //// step1: get input
+ //if (nrhs < 3) {
+ // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ // return;
+ //}
+ //int iDid = (int)(mxGetScalar(prhs[1]));
+ //int iProjectionNr = (int)(mxGetScalar(prhs[2]));
+
+ //// Get data object
+ //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+ //if (!pData) {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+
+ //CFloat32Data2D* res = NULL;
+ //// Projection Data
+ //if (pData->getType() == CFloat32Data3D::PROJECTION) {
+ // CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData);
+ // res = pData2->fetchProjection(iProjectionNr);
+ //}
+ //// Error
+ //else {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+ //
+ //// store data
+ //int iIndex = CData2DManager::getSingleton().store(res);
+
+ //// step4: set output
+ //if (1 <= nlhs) {
+ // plhs[0] = mxCreateDoubleScalar(iIndex);
+ //}
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_io_data('return_projection', id, slicenr);
+ */
+void astra_mex_data3d_return_projection(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ //// step1: get input
+ //if (nrhs < 3) {
+ // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ // return;
+ //}
+ //int iDid = (int)(mxGetScalar(prhs[1]));
+ //int iProjectionNr = (int)(mxGetScalar(prhs[2]));
+
+ //// Get data object
+ //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+ //if (!pData) {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+
+ //// Projection Data
+ //if (pData->getType() == CFloat32Data3D::PROJECTION) {
+ // CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData);
+ //// pData2->returnProjection(iProjectionNr);
+ //}
+ //// Error
+ //else {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * [id] = astra_mex_io_data('fetch_projection', id, slicenr);
+ */
+void astra_mex_data3d_fetch_slice_x(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ //// step1: get input
+ //if (nrhs < 3) {
+ // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ // return;
+ //}
+ //int iDid = (int)(mxGetScalar(prhs[1]));
+ //int iSliceNr = (int)(mxGetScalar(prhs[2]));
+
+ //// Get data object
+ //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+ //if (!pData) {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+
+ //CFloat32Data2D* res = NULL;
+ //// Projection Data
+ //if (pData->getType() == CFloat32Data3D::VOLUME) {
+ // CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
+ // res = pData2->fetchSliceX(iSliceNr);
+ //}
+ //// Error
+ //else {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+ //
+ //// store data
+ //int iIndex = CData2DManager::getSingleton().store(res);
+
+ //// step4: set output
+ //if (1 <= nlhs) {
+ // plhs[0] = mxCreateDoubleScalar(iIndex);
+ //}
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_io_data('return_slice_x', id, slicenr);
+ */
+void astra_mex_data3d_return_slice_x(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+// // step1: get input
+// if (nrhs < 3) {
+// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+// return;
+// }
+// int iDid = (int)(mxGetScalar(prhs[1]));
+// int iSliceNr = (int)(mxGetScalar(prhs[2]));
+//
+// // Get data object
+// CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+// if (!pData) {
+// mexErrMsgTxt("DataObject not valid. \n");
+// return;
+// }
+//
+// // Projection Data
+// if (pData->getType() == CFloat32Data3D::VOLUME) {
+// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
+//// TODO: think about returning slices
+//// pData2->returnSliceX(iSliceNr);
+// }
+// // Error
+// else {
+// mexErrMsgTxt("DataObject not valid. \n");
+// return;
+// }
+}
+
+
+//-----------------------------------------------------------------------------------------
+/**
+ * [id] = astra_mex_io_data('fetch_slice_y', id, slicenr);
+ */
+void astra_mex_data3d_fetch_slice_y(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ //// step1: get input
+ //if (nrhs < 3) {
+ // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ // return;
+ //}
+ //int iDid = (int)(mxGetScalar(prhs[1]));
+ //int iSliceNr = (int)(mxGetScalar(prhs[2]));
+
+ //// Get data object
+ //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+ //if (!pData) {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+
+ //CFloat32Data2D* res = NULL;
+ //// Projection Data
+ //if (pData->getType() == CFloat32Data3D::VOLUME) {
+ // CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
+ // res = pData2->fetchSliceY(iSliceNr);
+ //}
+ //// Error
+ //else {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+ //
+ //// store data
+ //int iIndex = CData2DManager::getSingleton().store(res);
+
+ //// step4: set output
+ //if (1 <= nlhs) {
+ // plhs[0] = mxCreateDoubleScalar(iIndex);
+ //}
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_io_data('return_slice_y', id, slicenr);
+ */
+void astra_mex_data3d_return_slice_y(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+// // step1: get input
+// if (nrhs < 3) {
+// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+// return;
+// }
+// int iDid = (int)(mxGetScalar(prhs[1]));
+// int iSliceNr = (int)(mxGetScalar(prhs[2]));
+//
+// // Get data object
+// CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+// if (!pData) {
+// mexErrMsgTxt("DataObject not valid. \n");
+// return;
+// }
+//
+// // Projection Data
+// if (pData->getType() == CFloat32Data3D::VOLUME) {
+// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
+//// TODO: think about returning slices
+//// pData2->returnSliceY(iSliceNr);
+// }
+// // Error
+// else {
+// mexErrMsgTxt("DataObject not valid. \n");
+// return;
+// }
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * [dim_x dim_y dim_z] = astra_mex_io_data('dimensions', id);
+ */
+void astra_mex_data3d_dimensions(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iDid = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get data object
+ CFloat32Data3D* pData;
+ if (!(pData = CData3DManager::getSingleton().get(iDid))) {
+ mexErrMsgTxt("DataObject not valid. \n");
+ return;
+ }
+
+ // step3: output
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(pData->getWidth());
+ }
+ if (2 <= nlhs) {
+ plhs[1] = mxCreateDoubleScalar(pData->getHeight());
+ }
+ if (3 <= nlhs) {
+ plhs[2] = mxCreateDoubleScalar(pData->getDepth());
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * [geom] = astra_mex_data3d('geometry', id);
+ */
+void astra_mex_data3d_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ //// Get input
+ //if (nrhs < 2) {
+ // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ // return;
+ //}
+ //int iDid = (int)(mxGetScalar(prhs[1]));
+
+ //// Get data object
+ //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+ //if (!pData) {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+
+ //// Projection Data
+ //if (pData->getType() == CFloat32Data3D::PROJECTION) {
+ // CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData);
+ // CProjectionGeometry3D* pProjGeom = pData2->getGeometry();
+ // XMLDocument* config = pProjGeom->toXML();
+
+ // if (1 <= nlhs) {
+ // plhs[0] = XML2struct(config);
+ // }
+ //}
+ //// Volume Data
+ //else if (pData->getType() == CFloat32Data3D::VOLUME) {
+ //// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
+ //// CVolumeGeometry2D* pVolGeom = pData2->getGeometry2D(iSliceNr);
+ //// if (1 <= nlhs) {
+ //// plhs[0] = createVolumeGeometryStruct(pVolGeom);
+ //// }
+ //}
+ //// Error
+ //else {
+ // mexErrMsgTxt("Type not valid. \n");
+ // return;
+ //}
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * [geom_xml] = astra_mex_data3d('geometry_xml', id);
+ */
+void astra_mex_data3d_geometry_xml(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ //// Get input
+ //if (nrhs < 2) {
+ // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ // return;
+ //}
+ //int iDid = (int)(mxGetScalar(prhs[1]));
+
+ //// Get data object
+ //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
+ //if (!pData) {
+ // mexErrMsgTxt("DataObject not valid. \n");
+ // return;
+ //}
+
+ //// Projection Data
+ //if (pData->getType() == CFloat32Data3D::PROJECTION) {
+ // CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData);
+ // CProjectionGeometry3D* pProjGeom = pData2->getGeometry();
+ // XMLDocument* config = pProjGeom->toXML();
+
+ // if (1 <= nlhs) {
+ // plhs[0] = mxCreateString(config->getRootNode()->toString().c_str());
+ // }
+ //}
+ //// Volume Data
+ //else if (pData->getType() == CFloat32Data3D::VOLUME) {
+ //// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
+ //// CVolumeGeometry2D* pVolGeom = pData2->getGeometry2D(iSliceNr);
+ //// if (1 <= nlhs) {
+ //// plhs[0] = createVolumeGeometryStruct(pVolGeom);
+ //// }
+ //}
+ //// Error
+ //else {
+ // mexErrMsgTxt("Type not valid. \n");
+ // return;
+ //}
+}
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_data3d('delete', did1, did2, ...);
+ */
+void astra_mex_data3d_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: read input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ for (int i = 1; i < nrhs; i++) {
+ int iDataID = (int)(mxGetScalar(prhs[i]));
+ CData3DManager::getSingleton().remove(iDataID);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_data3d('clear');
+ */
+void astra_mex_data3d_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ CData3DManager::getSingleton().clear();
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_data3d('info');
+ */
+void astra_mex_data3d_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ mexPrintf("%s", astra::CData3DManager::getSingleton().info().c_str());
+}
+
+//-----------------------------------------------------------------------------------------
+
+static void printHelp()
+{
+ mexPrintf("Please specify a mode of operation.\n");
+ mexPrintf("Valid modes: create, create_cache, get, get_single, delete, clear, info\n");
+ mexPrintf(" fetch_projection, return_projection, fetch_slice[_z],\n");
+ mexPrintf(" return_slice[_z], fetch_slice_x, return slice_x\n");
+ mexPrintf(" fetch_slice_y, return slice_y, dimensions, geometry\n");
+ mexPrintf(" geometry_xml\n");
+}
+
+
+//-----------------------------------------------------------------------------------------
+/**
+ * ... = astra_mex_io_data(mode,...);
+ */
+void mexFunction(int nlhs, mxArray* plhs[],
+ int nrhs, const mxArray* prhs[])
+{
+
+ // INPUT: Mode
+ string sMode = "";
+ if (1 <= nrhs) {
+ sMode = mex_util_get_string(prhs[0]);
+ } else {
+ printHelp();
+ return;
+ }
+
+ // 3D data
+ if (sMode == std::string("create")) {
+ astra_mex_data3d_create(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("create_cache")) {
+ astra_mex_data3d_create_cache(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("get")) {
+ astra_mex_data3d_get(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("get_single")) {
+ astra_mex_data3d_get_single(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("store") ||
+ sMode == std::string("set")) {
+ astra_mex_data3d_store(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("delete")) {
+ astra_mex_data3d_delete(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "clear") {
+ astra_mex_data3d_clear(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "info") {
+ astra_mex_data3d_info(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("fetch_projection")) {
+ astra_mex_data3d_fetch_projection(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("return_projection")) {
+ astra_mex_data3d_return_projection(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("fetch_slice") || sMode == std::string("fetch_slice_z")) {
+ astra_mex_data3d_fetch_slice_z(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("return_slice") || sMode == std::string("return_slice_z")) {
+ astra_mex_data3d_return_slice_z(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("fetch_slice_x")) {
+ astra_mex_data3d_fetch_slice_x(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("return_slice_x")) {
+ astra_mex_data3d_return_slice_x(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("fetch_slice_y")) {
+ astra_mex_data3d_fetch_slice_y(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("return_slice_y")) {
+ astra_mex_data3d_return_slice_y(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("dimensions")) {
+ astra_mex_data3d_dimensions(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("geometry")) {
+ astra_mex_data3d_geometry(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("geometry_xml")) {
+ astra_mex_data3d_geometry_xml(nlhs, plhs, nrhs, prhs);
+ } else {
+ printHelp();
+ }
+
+ return;
+}
+
+
diff --git a/matlab/mex/astra_mex_data3d_vc08.vcproj b/matlab/mex/astra_mex_data3d_vc08.vcproj
new file mode 100644
index 0000000..2e69c16
--- /dev/null
+++ b/matlab/mex/astra_mex_data3d_vc08.vcproj
@@ -0,0 +1,588 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="astra_mex_data3d"
+ ProjectGUID="{0BEC029B-0929-4BF9-BD8B-9C9806A52065}"
+ RootNamespace="astraMatlab"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\astra_mex_data3d_c.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/matlab/mex/astra_mex_matrix_c.cpp b/matlab/mex/astra_mex_matrix_c.cpp
new file mode 100644
index 0000000..accaab5
--- /dev/null
+++ b/matlab/mex/astra_mex_matrix_c.cpp
@@ -0,0 +1,437 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+/** \file astra_mex_matrix_c.cpp
+ *
+ * \brief Create sparse (projection) matrices in the ASTRA workspace
+ */
+#include <mex.h>
+#include "mexHelpFunctions.h"
+
+#include <list>
+
+#include "astra/Globals.h"
+
+#include "astra/AstraObjectManager.h"
+
+#include "astra/SparseMatrix.h"
+
+using namespace std;
+using namespace astra;
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_matrix('delete', id1, id2, ...);
+ *
+ * Delete one or more data objects currently stored in the astra-library.
+ * id1, id2, ... : identifiers of the 2d data objects as stored in the astra-library.
+ */
+void astra_mex_matrix_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: read input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ // step2: delete all specified data objects
+ for (int i = 1; i < nrhs; i++) {
+ int iDataID = (int)(mxGetScalar(prhs[i]));
+ CMatrixManager::getSingleton().remove(iDataID);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_matrix('clear');
+ *
+ * Delete all data objects currently stored in the astra-library.
+ */
+void astra_mex_matrix_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ CMatrixManager::getSingleton().clear();
+}
+
+
+
+static bool matlab_to_astra(const mxArray* _rhs, CSparseMatrix* _pMatrix)
+{
+ // Check input
+ if (!mxIsSparse (_rhs)) {
+ mexErrMsgTxt("Argument is not a valid MATLAB sparse matrix.\n");
+ return false;
+ }
+ if (!_pMatrix->isInitialized()) {
+ mexErrMsgTxt("Couldn't initialize data object.\n");
+ return false;
+ }
+
+ unsigned int iHeight = mxGetM(_rhs);
+ unsigned int iWidth = mxGetN(_rhs);
+ unsigned long lSize = mxGetNzmax(_rhs);
+
+ if (_pMatrix->m_lSize < lSize || _pMatrix->m_iHeight < iHeight) {
+ // TODO: support resizing?
+ mexErrMsgTxt("Matrix too large to store in this object.\n");
+ return false;
+ }
+
+ // Transpose matrix, as matlab stores a matrix column-by-column
+ // but we want it row-by-row.
+ // 1. Compute sizes of rows. We store these in _pMatrix->m_plRowStarts.
+ // 2. Fill data structure
+ // Complexity: O( #rows + #entries )
+
+ for (unsigned int i = 0; i <= iHeight; ++i)
+ _pMatrix->m_plRowStarts[i] = 0;
+
+ mwIndex *colStarts = mxGetJc(_rhs);
+ mwIndex *rowIndices = mxGetIr(_rhs);
+ double *floatValues = 0;
+ bool *boolValues = 0;
+ bool bLogical = mxIsLogical(_rhs);
+ if (bLogical)
+ boolValues = mxGetLogicals(_rhs);
+ else
+ floatValues = mxGetPr(_rhs);
+
+ for (mwIndex i = 0; i < colStarts[iWidth]; ++i) {
+ unsigned int iRow = rowIndices[i];
+ assert(iRow < iHeight);
+ _pMatrix->m_plRowStarts[iRow+1]++;
+ }
+
+ // Now _pMatrix->m_plRowStarts[i+1] is the number of entries in row i
+
+ for (unsigned int i = 1; i <= iHeight; ++i)
+ _pMatrix->m_plRowStarts[i] += _pMatrix->m_plRowStarts[i-1];
+
+ // Now _pMatrix->m_plRowStarts[i+1] is the number of entries in rows <= i,
+ // so the intended start of row i+1
+
+ int iCol = 0;
+ for (mwIndex i = 0; i < colStarts[iWidth]; ++i) {
+ while (i >= colStarts[iCol+1])
+ iCol++;
+
+ unsigned int iRow = rowIndices[i];
+ assert(iRow < iHeight);
+ float32 fVal;
+ if (bLogical)
+ fVal = (float32)boolValues[i];
+ else
+ fVal = (float32)floatValues[i];
+
+ unsigned long lIndex = _pMatrix->m_plRowStarts[iRow]++;
+ _pMatrix->m_pfValues[lIndex] = fVal;
+ _pMatrix->m_piColIndices[lIndex] = iCol;
+ }
+
+ // Now _pMatrix->m_plRowStarts[i] is the start of row i+1
+
+ for (unsigned int i = iHeight; i > 0; --i)
+ _pMatrix->m_plRowStarts[i] = _pMatrix->m_plRowStarts[i-1];
+ _pMatrix->m_plRowStarts[0] = 0;
+
+#if 0
+ // Debugging: dump matrix
+ for (unsigned int i = 0; i < iHeight; ++i) {
+ printf("Row %d: %ld-%ld\n", i, _pMatrix->m_plRowStarts[i], _pMatrix->m_plRowStarts[i+1]);
+ for (unsigned long j = _pMatrix->m_plRowStarts[i]; j < _pMatrix->m_plRowStarts[i+1]; ++j) {
+ printf("(%d,%d) = %f\n", i, _pMatrix->m_piColIndices[j], _pMatrix->m_pfValues[j]);
+ }
+ }
+#endif
+
+ return true;
+}
+
+static bool astra_to_matlab(const CSparseMatrix* _pMatrix, mxArray*& _lhs)
+{
+ if (!_pMatrix->isInitialized()) {
+ mexErrMsgTxt("Uninitialized data object.\n");
+ return false;
+ }
+
+ unsigned int iHeight = _pMatrix->m_iHeight;
+ unsigned int iWidth = _pMatrix->m_iWidth;
+ unsigned long lSize = _pMatrix->m_lSize;
+
+ _lhs = mxCreateSparse(iHeight, iWidth, lSize, mxREAL);
+ if (!mxIsSparse (_lhs)) {
+ mexErrMsgTxt("Couldn't initialize matlab sparse matrix.\n");
+ return false;
+ }
+
+ mwIndex *colStarts = mxGetJc(_lhs);
+ mwIndex *rowIndices = mxGetIr(_lhs);
+ double *floatValues = mxGetPr(_lhs);
+
+ for (unsigned int i = 0; i <= iWidth; ++i)
+ colStarts[i] = 0;
+
+ for (unsigned int i = 0; i < _pMatrix->m_plRowStarts[iHeight]; ++i) {
+ unsigned int iCol = _pMatrix->m_piColIndices[i];
+ assert(iCol < iWidth);
+ colStarts[iCol+1]++;
+ }
+ // Now _pMatrix->m_plRowStarts[i+1] is the number of entries in row i
+
+ for (unsigned int i = 1; i <= iWidth; ++i)
+ colStarts[i] += colStarts[i-1];
+ // Now _pMatrix->m_plRowStarts[i+1] is the number of entries in rows <= i,
+ // so the intended start of row i+1
+
+ unsigned int iRow = 0;
+ for (unsigned int i = 0; i < _pMatrix->m_plRowStarts[iHeight]; ++i) {
+ while (i >= _pMatrix->m_plRowStarts[iRow+1])
+ iRow++;
+
+ unsigned int iCol = _pMatrix->m_piColIndices[i];
+ assert(iCol < iWidth);
+ double fVal = _pMatrix->m_pfValues[i];
+ unsigned long lIndex = colStarts[iCol]++;
+ floatValues[lIndex] = fVal;
+ rowIndices[lIndex] = iRow;
+ }
+ // Now _pMatrix->m_plRowStarts[i] is the start of row i+1
+
+ for (unsigned int i = iWidth; i > 0; --i)
+ colStarts[i] = colStarts[i-1];
+ colStarts[0] = 0;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------------------
+/** id = astra_mex_matrix('create', data);
+ *
+ * Create a new matrix object in the astra-library.
+ * data: a sparse MATLAB matrix containing the data.
+ * id: identifier of the matrix object as it is now stored in the astra-library.
+ */
+void astra_mex_matrix_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[])
+{
+ // step1: get datatype
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ if (!mxIsSparse (prhs[1])) {
+ mexErrMsgTxt("Argument is not a valid MATLAB sparse matrix.\n");
+ return;
+ }
+
+ unsigned int iHeight = mxGetM(prhs[1]);
+ unsigned int iWidth = mxGetN(prhs[1]);
+ unsigned long lSize = mxGetNzmax(prhs[1]);
+
+ CSparseMatrix* pMatrix = new CSparseMatrix(iHeight, iWidth, lSize);
+
+ // Check initialization
+ if (!pMatrix->isInitialized()) {
+ mexErrMsgTxt("Couldn't initialize data object.\n");
+ delete pMatrix;
+ return;
+ }
+
+ bool bResult = matlab_to_astra(prhs[1], pMatrix);
+
+ if (!bResult) {
+ mexErrMsgTxt("Failed to create data object.\n");
+ delete pMatrix;
+ return;
+ }
+
+ // store data object
+ int iIndex = CMatrixManager::getSingleton().store(pMatrix);
+
+ // return data id
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(iIndex);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_matrix('store', id, data);
+ *
+ * Store a sparse MATLAB matrix in an existing astra matrix dataobject.
+ * id: identifier of the 2d data object as stored in the astra-library.
+ * data: a sparse MATLAB matrix.
+ */
+void astra_mex_matrix_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: input
+ if (nrhs < 3) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ if (!mxIsDouble(prhs[1])) {
+ mexErrMsgTxt("Identifier should be a scalar value. \n");
+ return;
+ }
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get data object
+ CSparseMatrix* pMatrix = astra::CMatrixManager::getSingleton().get(iDataID);
+ if (!pMatrix || !pMatrix->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ bool bResult = matlab_to_astra(prhs[2], pMatrix);
+ if (!bResult) {
+ mexErrMsgTxt("Failed to store matrix.\n");
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** geom = astra_mex_matrix('get_size', id);
+ *
+ * Fetch the dimensions and size of a matrix stored in the astra-library.
+ * id: identifier of the 2d data object as stored in the astra-library.
+ * geom: a 1x2 matrix containing [rows, columns]
+ */
+void astra_mex_matrix_get_size(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ if (!mxIsDouble(prhs[1])) {
+ mexErrMsgTxt("Identifier should be a scalar value. \n");
+ return;
+ }
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get data object
+ CSparseMatrix* pMatrix = astra::CMatrixManager::getSingleton().get(iDataID);
+ if (!pMatrix || !pMatrix->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ // create output
+ // TODO
+}
+
+//-----------------------------------------------------------------------------------------
+/** data = astra_mex_matrix('get', id);
+ *
+ * Fetch data from the astra-library to a MATLAB matrix.
+ * id: identifier of the matrix data object as stored in the astra-library.
+ * data: MATLAB
+ */
+void astra_mex_matrix_get(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: check input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ if (!mxIsDouble(prhs[1])) {
+ mexErrMsgTxt("Identifier should be a scalar value. \n");
+ return;
+ }
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get data object
+ CSparseMatrix* pMatrix = astra::CMatrixManager::getSingleton().get(iDataID);
+ if (!pMatrix || !pMatrix->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ // create output
+ if (1 <= nlhs) {
+ bool bResult = astra_to_matlab(pMatrix, plhs[0]);
+ if (!bResult) {
+ mexErrMsgTxt("Failed to get matrix.\n");
+ }
+ }
+
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_matrix('info');
+ *
+ * Print information about all the matrix objects currently stored in the astra-library.
+ */
+void astra_mex_matrix_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ mexPrintf("%s", astra::CMatrixManager::getSingleton().info().c_str());
+}
+
+//-----------------------------------------------------------------------------------------
+
+static void printHelp()
+{
+ mexPrintf("Please specify a mode of operation.\n");
+ mexPrintf("Valid modes: get, delete, clear, store, create, get_size, info\n");
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * ... = astra_mex_matrix(type,...);
+ */
+void mexFunction(int nlhs, mxArray* plhs[],
+ int nrhs, const mxArray* prhs[])
+{
+
+ // INPUT0: Mode
+ string sMode = "";
+ if (1 <= nrhs) {
+ sMode = mex_util_get_string(prhs[0]);
+ } else {
+ printHelp();
+ return;
+ }
+
+ // SWITCH (MODE)
+ if (sMode == std::string("get")) {
+ astra_mex_matrix_get(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("delete")) {
+ astra_mex_matrix_delete(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "clear") {
+ astra_mex_matrix_clear(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("store")) {
+ astra_mex_matrix_store(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("create")) {
+ astra_mex_matrix_create(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("get_size")) {
+ astra_mex_matrix_get_size(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("info")) {
+ astra_mex_matrix_info(nlhs, plhs, nrhs, prhs);
+ } else {
+ printHelp();
+ }
+
+ return;
+}
+
+
diff --git a/matlab/mex/astra_mex_matrix_vc08.vcproj b/matlab/mex/astra_mex_matrix_vc08.vcproj
new file mode 100644
index 0000000..47509f6
--- /dev/null
+++ b/matlab/mex/astra_mex_matrix_vc08.vcproj
@@ -0,0 +1,591 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="astra_mex_matrix"
+ ProjectGUID="{9D041710-2119-4230-BCF2-5FBE753FDE49}"
+ RootNamespace="astraMatlab"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\;"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;$(CUDA_INC_PATH)&quot;;$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ BrowseInformation="1"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\astra_mex_matrix_c.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp
new file mode 100644
index 0000000..1385863
--- /dev/null
+++ b/matlab/mex/astra_mex_projector3d_c.cpp
@@ -0,0 +1,433 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+/** \file astra_mex_projector3d_c.cpp
+ *
+ * \brief Create and manage 3d projectors in the ASTRA workspace
+ */
+
+#include <mex.h>
+#include "mexHelpFunctions.h"
+
+#include "astra/Globals.h"
+
+#include "astra/Projector3D.h"
+#include "astra/AstraObjectManager.h"
+#include "astra/AstraObjectFactory.h"
+
+#include "astra/ProjectionGeometry3D.h"
+#include "astra/VolumeGeometry3D.h"
+
+#include <map>
+#include <vector>
+
+using namespace std;
+using namespace astra;
+
+//-----------------------------------------------------------------------------------------
+/**
+* [pid] = astra_mex_projector('create', cfgstruct);
+*/
+void astra_mex_projector3d_create(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ if (!mxIsStruct(prhs[1])) {
+ mexErrMsgTxt("Argument 1 not a valid MATLAB struct. \n");
+ }
+
+ // turn MATLAB struct to an XML-based Config object
+ XMLDocument* xml = struct2XML("Projector3D", prhs[1]);
+ Config cfg;
+ cfg.self = xml->getRootNode();
+
+ // create algorithm
+ CProjector3D* pProj = CProjector3DFactory::getSingleton().create(cfg);
+ if (pProj == NULL) {
+ mexErrMsgTxt("Error creating Projector3D. \n");
+ return;
+ }
+
+ // store projector
+ int iIndex = CProjector3DManager::getSingleton().store(pProj);
+
+ // step4: set output
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(iIndex);
+ }
+
+ }
+
+//-----------------------------------------------------------------------------------------
+/**
+* astra_mex_projector3d('destroy', pid1, pid2, ...);
+*/
+void astra_mex_projector3d_destroy(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: read input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ for (int i = 1; i < nrhs; i++) {
+ int iPid = (int)(mxGetScalar(prhs[i]));
+ CProjector3DManager::getSingleton().remove(iPid);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_projector3d('clear');
+ */
+void astra_mex_projector3d_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ CProjector3DManager::getSingleton().clear();
+}
+
+
+//-----------------------------------------------------------------------------------------
+/**
+* [proj_geom] = astra_mex_projector3d('get_projection_geometry', pid);
+*/
+void astra_mex_projector3d_get_projection_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: read input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get projector
+ CProjector3D* pProjector;
+ if (!(pProjector = CProjector3DManager::getSingleton().get(iPid))) {
+ mexErrMsgTxt("Projector not found.\n");
+ return;
+ }
+
+ // step3: get projection_geometry and turn it into a MATLAB struct
+ //if (1 <= nlhs) {
+ // plhs[0] = createProjectionGeometryStruct(pProjector->getProjectionGeometry());
+ //}
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+* [recon_geom] = astra_mex_projector3d('get_volume_geometry', pid);
+*/
+void astra_mex_projector3d_get_reconstruction_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: read input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get projector
+ CProjector3D* pProjector;
+ if (!(pProjector = CProjector3DManager::getSingleton().get(iPid))) {
+ mexErrMsgTxt("Projector not found.\n");
+ return;
+ }
+
+ // step3: get projection_geometry and turn it into a MATLAB struct
+ //if (1 <= nlhs) {
+ // plhs[0] = createVolumeGeometryStruct(pProjector->getVolumeGeometry());
+ //}
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+* [weights] = astra_mex_projector3d('weights_single_ray', pid, projection_index, detector_index);
+*/
+void astra_mex_projector_weights_single_ray(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ //// step1: get input
+ //if (nrhs < 4) {
+ // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ // return;
+ //}
+ //int iPid = (int)(mxGetScalar(prhs[1]));
+ //int iProjectionIndex = (int)(mxGetScalar(prhs[2]));
+ //int iDetectorIndex = (int)(mxGetScalar(prhs[3]));
+
+ //// step2: get projector
+ //CProjector3D* pProjector;
+ //if (!(pProjector = CProjector3DManager::getSingleton().get(iPid))) {
+ // mexErrMsgTxt("Projector not found.\n");
+ // return;
+ //}
+ //
+ //// step3: create output vars
+ //int iStoredPixelCount;
+ //int iMaxPixelCount = pProjector->getProjectionWeightsCount(iProjectionIndex);
+ //SWeightedPixel* pPixelsWeights = new SWeightedPixel3D[iMaxPixelCount];
+ //
+ //// step4: perform operation
+ //pProjector->computeSingleRayWeights(iProjectionIndex,
+ // iDetectorIndex,
+ // pPixelsWeights,
+ // iMaxPixelCount,
+ // iStoredPixelCount);
+
+ //// step5: return output
+ //if (1 <= nlhs) {
+ // mwSize dims[2];
+ // dims[0] = iStoredPixelCount;
+ // dims[1] = 2;
+
+ // plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
+ // double* out = mxGetPr(plhs[0]);
+
+ // for (int col = 0; col < iStoredPixelCount; col++) {
+ // out[col] = pPixelsWeights[col].m_iIndex;
+ // out[iStoredPixelCount+col] = pPixelsWeights[col].m_fWeight;
+ // //cout << pPixelsWeights[col].m_iIndex << " " << pPixelsWeights[col].m_fWeight <<endl;
+ // }
+ //}
+ //
+ //// garbage collection
+ //delete[] pPixelsWeights;
+}
+
+////-----------------------------------------------------------------------------------------
+///**
+//* [weights] = astra_mex_projector('weights_projection', pid, projection_index);
+//*/
+//void astra_mex_projector_weights_projection(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+//{
+// // step1: get input
+// if (nrhs < 3) {
+// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+// return;
+// }
+// int iPid = (int)(mxGetScalar(prhs[1]));
+// int iProjectionIndex = (int)(mxGetScalar(prhs[2]));
+//
+// // step2: get projector
+// CProjector2D* pProjector;
+// if (!(pProjector = CProjectorManager::getSingleton().get(iPid))) {
+// mexErrMsgTxt("Projector not found.\n");
+// return;
+// }
+//
+// // step3: create output vars
+// SWeightedPixel2D* pPixelsWheights = new SWeightedPixel2D[pProjector->getProjectionWeightsCount(iProjectionIndex)];
+// int* piRayStoredPixelCount = new int[pProjector->getProjectionGeometry()->getDetectorCount()];
+//
+// // step4: perform operation
+// pProjector->computeProjectionRayWeights(iProjectionIndex, pPixelsWheights, piRayStoredPixelCount);
+//
+// // step5: return output
+// if (1 <= nlhs) {
+// // get basic values
+// int iMatrixSize = pProjector->getVolumeGeometry()->getWindowLengthX() *
+// pProjector->getVolumeGeometry()->getWindowLengthY();
+// int iDetectorCount = pProjector->getProjectionGeometry()->getDetectorCount();
+// int iTotalStoredPixelCount = 0;
+// for (int i = 0; i < iDetectorCount; i++) {
+// iTotalStoredPixelCount += piRayStoredPixelCount[i];
+// }
+//
+// // create matlab sparse matrix
+// plhs[0] = mxCreateSparse(iMatrixSize, // number of rows (#pixels)
+// iDetectorCount, // number of columns (#detectors)
+// iTotalStoredPixelCount, // number of non-zero elements
+// mxREAL); // element type
+// double* values = mxGetPr(plhs[0]);
+// mwIndex* rows = mxGetIr(plhs[0]);
+// mwIndex* cols = mxGetJc(plhs[0]);
+//
+// int currentBase = 0;
+// int currentIndex = 0;
+// for (int i = 0; i < iDetectorCount; i++) {
+// for (int j = 0; j < piRayStoredPixelCount[i]; j++) {
+// values[currentIndex + j] = pPixelsWheights[currentBase + j].m_fWeight;
+// rows[currentIndex + j] = pPixelsWheights[currentBase + j].m_iIndex;
+// }
+//
+// currentBase += pProjector->getProjectionWeightsCount(iProjectionIndex) / pProjector->getProjectionGeometry()->getDetectorCount();
+// currentIndex += piRayStoredPixelCount[i];
+// }
+// cols[0] = piRayStoredPixelCount[0];
+// for (int j = 1; j < iDetectorCount; j++) {
+// cols[j] = cols[j-1] + piRayStoredPixelCount[j];
+// }
+// cols[iDetectorCount] = iTotalStoredPixelCount;
+// }
+//
+//}
+//
+////-----------------------------------------------------------------------------------------
+///**
+//* output = astra_mex_projector('splat', pid, x, y);
+//*/
+//void astra_mex_projector_splat(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+//{
+// // step1: get input
+// if (nrhs < 4) {
+// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+// return;
+// }
+// int iPid = (int)(mxGetScalar(prhs[1]));
+// int iX = (int)(mxGetScalar(prhs[2]));
+// int iY = (int)(mxGetScalar(prhs[3]));
+//
+// // step2: get projector
+// CProjector2D* pProjector;
+// if (!(pProjector = CProjectorManager::getSingleton().get(iPid))) {
+// mexErrMsgTxt("Projector not found.\n");
+// return;
+// }
+//
+// // step3: perform action
+// vector<SDetector2D> detinfo = pProjector->projectPoint(iX, iY);
+//
+// // step4: output
+// if (nlhs <= 1) {
+// plhs[0] = mxCreateDoubleMatrix(detinfo.size(), // # rows
+// 2, // # cols
+// mxREAL); // datatype 32-bits
+// double* out = mxGetPr(plhs[0]);
+//
+// // fill up output
+// int i = 0;
+// for (int x = 0; x < detinfo.size() ; x++) {
+// out[i] = detinfo[x].m_iAngleIndex;
+// i++;
+// }
+// for (int x = 0; x < detinfo.size() ; x++) {
+// out[i] = detinfo[x].m_iDetectorIndex;
+// i++;
+// }
+// }
+//
+//
+//}
+
+//-----------------------------------------------------------------------------------------
+/** result = astra_mex_projector3d('is_cuda', id);
+ *
+ * Return is the specified projector is a cuda projector.
+ * id: identifier of the projector object as stored in the astra-library.
+ */
+void astra_mex_projector3d_is_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get projector
+ CProjector3D* pProjector = CProjector3DManager::getSingleton().get(iPid);
+ if (!pProjector || !pProjector->isInitialized()) {
+ mexErrMsgTxt("Projector not initialized.\n");
+ return;
+ }
+
+#ifdef ASTRA_CUDA
+ CCudaProjector3D* pCP = dynamic_cast<CCudaProjector3D*>(pProjector);
+ plhs[0] = mxCreateLogicalScalar(pCP ? 1 : 0);
+#else
+ plhs[0] = mxCreateLogicalScalar(0);
+#endif
+}
+
+
+//-----------------------------------------------------------------------------------------
+/**
+ * astra_mex_projector3d('help');
+ */
+void astra_mex_projector3d_help(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ cout << "astra_mex_projector3d help:" <<endl;
+ cout << "---------------------------" <<endl;
+}
+
+
+//-----------------------------------------------------------------------------------------
+
+static void printHelp()
+{
+ mexPrintf("Please specify a mode of operation.\n");
+ mexPrintf("Valid modes: create, delete, clear, get_projection_geometry,\n");
+ mexPrintf(" get_volume_geometry, weights_single_ray, weights_projection\n");
+ mexPrintf(" splat, is_cuda\n");
+}
+
+//-----------------------------------------------------------------------------------------
+/**
+ * [pid] = astra_mex_projector('read', projection_geometry, reconstruction_geometry);
+ */
+void mexFunction(int nlhs, mxArray* plhs[],
+ int nrhs, const mxArray* prhs[])
+{
+ // INPUT: Mode
+ string sMode = "";
+ if (1 <= nrhs) {
+ sMode = mex_util_get_string(prhs[0]);
+ } else {
+ printHelp();
+ return;
+ }
+
+ // SWITCH (MODE)
+ if (sMode == "create") {
+ astra_mex_projector3d_create(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "delete") {
+ astra_mex_projector3d_destroy(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "clear") {
+ astra_mex_projector3d_clear(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "get_projection_geometry") {
+ astra_mex_projector3d_get_projection_geometry(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "get_volume_geometry") {
+ astra_mex_projector3d_get_reconstruction_geometry(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "weights_single_ray") {
+ astra_mex_projector_weights_single_ray(nlhs, plhs, nrhs, prhs);
+ //} else if (sMode == "weights_projection") {
+ // astra_mex_projector_weights_projection(nlhs, plhs, nrhs, prhs);
+ //} else if (sMode == "splat") {
+ // astra_mex_projector_splat(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "is_cuda") {
+ astra_mex_projector3d_is_cuda(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "help") {
+ astra_mex_projector3d_help(nlhs, plhs, nrhs, prhs);
+ } else {
+ printHelp();
+ }
+ return;
+}
+
+
diff --git a/matlab/mex/astra_mex_projector3d_vc08.vcproj b/matlab/mex/astra_mex_projector3d_vc08.vcproj
new file mode 100644
index 0000000..bedc53b
--- /dev/null
+++ b/matlab/mex/astra_mex_projector3d_vc08.vcproj
@@ -0,0 +1,588 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="astra_mex_projector3d"
+ ProjectGUID="{F94CCD79-AA11-42DF-AC8A-6C9D2238A883}"
+ RootNamespace="astraMatlab"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\;"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\;"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\;"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\astra_mex_projector3d_c.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/matlab/mex/astra_mex_projector_c.cpp b/matlab/mex/astra_mex_projector_c.cpp
new file mode 100644
index 0000000..5cbe502
--- /dev/null
+++ b/matlab/mex/astra_mex_projector_c.cpp
@@ -0,0 +1,510 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+/** \file astra_mex_projector_c.cpp
+ *
+ * \brief Create and manage 2d projectors in the ASTRA workspace
+ */
+#include "astra/Globals.h"
+
+#include <mex.h>
+#include "mexHelpFunctions.h"
+
+#include "astra/AstraObjectManager.h"
+#include "astra/Projector2D.h"
+#include "astra/AstraObjectFactory.h"
+
+#include "astra/Float32VolumeData2D.h"
+
+#include "astra/ProjectionGeometry2D.h"
+#include "astra/ParallelProjectionGeometry2D.h"
+#include "astra/VolumeGeometry2D.h"
+
+
+#include <map>
+#include <vector>
+
+using namespace std;
+using namespace astra;
+
+//-----------------------------------------------------------------------------------------
+/** id = astra_mex_projector('create', cfg);
+ *
+ * Create and configure a new projector object.
+ * cfg: MATLAB struct containing the configuration parameters, see doxygen documentation for details.
+ * id: identifier of the projector object as it is now stored in the astra-library.
+ */
+void astra_mex_projector_create(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ int iIndex = 0;
+
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ if (!mxIsStruct(prhs[1])) {
+ mexErrMsgTxt("Argument 1 not a valid MATLAB struct. \n");
+ }
+
+
+ // turn MATLAB struct to an XML-based Config object
+ XMLDocument* xml = struct2XML("Projector2D", prhs[1]);
+ Config cfg;
+ cfg.self = xml->getRootNode();
+
+ // create algorithm
+ CProjector2D* pProj = CProjector2DFactory::getSingleton().create(cfg);
+ if (pProj == NULL) {
+ delete xml;
+ mexErrMsgTxt("Error creating projector. \n");
+ return;
+ }
+
+ delete xml;
+
+ // store projector
+ iIndex = CProjector2DManager::getSingleton().store(pProj);
+
+ // step4: set output
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(iIndex);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_projector('delete', id1, id2, ...);
+ *
+ * Delete one or more projector objects currently stored in the astra-library.
+ * id1, id2, ... : identifiers of the projector objects as stored in the astra-library.
+ */
+void astra_mex_projector_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: read input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+
+ for (int i = 1; i < nrhs; i++) {
+ int iPid = (int)(mxGetScalar(prhs[i]));
+ CProjector2DManager::getSingleton().remove(iPid);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_projector('clear');
+ *
+ * Delete all projector objects currently stored in the astra-library.
+ */
+void astra_mex_projector_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ CProjector2DManager::getSingleton().clear();
+}
+
+//-----------------------------------------------------------------------------------------
+/** astra_mex_projector('info');
+ *
+ * Print information about all the projector objects currently stored in the astra-library.
+ */
+void astra_mex_projector_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ mexPrintf("%s", astra::CProjector2DManager::getSingleton().info().c_str());
+}
+
+//-----------------------------------------------------------------------------------------
+/** proj_geom = astra_mex_projector('projection_geometry', id);
+ *
+ * Fetch the projection geometry of a certain projector.
+ * id: identifier of the projector object as stored in the astra-library.
+ * proj_geom: MATLAB struct containing all information about the projection geometry
+*/
+void astra_mex_projector_projection_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: read input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get projector
+ CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid);
+ if (!pProjector || !pProjector->isInitialized()) {
+ mexErrMsgTxt("Projector not initialized.\n");
+ return;
+ }
+
+ // step3: get projection_geometry and turn it into a MATLAB struct
+ if (1 <= nlhs) {
+ plhs[0] = createProjectionGeometryStruct(pProjector->getProjectionGeometry());
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** vol_geom = astra_mex_projector('volume_geometry', id);
+ *
+ * Fetch the volume geometry of a certain projector.
+ * id: identifier of the projector object as stored in the astra-library.
+ * vol_geom: MATLAB struct containing all information about the volume geometry
+ */
+void astra_mex_projector_volume_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: read input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get projector
+ CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid);
+ if (!pProjector || !pProjector->isInitialized()) {
+ mexErrMsgTxt("Projector not initialized.\n");
+ return;
+ }
+
+ // step3: get projection_geometry and turn it into a MATLAB struct
+ if (1 <= nlhs) {
+ plhs[0] = createVolumeGeometryStruct(pProjector->getVolumeGeometry());
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** weights = astra_mex_projector('weights_single_ray', id, projection_index, detector_index);
+ *
+ * Calculate the nonzero weights of a certain projection ray.
+ * id: identifier of the projector object as stored in the astra-library.
+ * projection_index: index of the projection angle
+ * detector_index: index of the detector
+ * weights: list of computed weights [pixel_index, weight]
+ */
+void astra_mex_projector_weights_single_ray(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get input
+ if (nrhs < 4) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+ int iProjectionIndex = (int)(mxGetScalar(prhs[2]));
+ int iDetectorIndex = (int)(mxGetScalar(prhs[3]));
+
+ // step2: get projector
+ CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid);
+ if (!pProjector || !pProjector->isInitialized()) {
+ mexErrMsgTxt("Projector not initialized.\n");
+ return;
+ }
+
+ // step3: create output vars
+ int iStoredPixelCount;
+ int iMaxPixelCount = pProjector->getProjectionWeightsCount(iProjectionIndex);
+ SPixelWeight* pPixelsWeights = new SPixelWeight[iMaxPixelCount];
+
+ // step4: perform operation
+ pProjector->computeSingleRayWeights(iProjectionIndex,
+ iDetectorIndex,
+ pPixelsWeights,
+ iMaxPixelCount,
+ iStoredPixelCount);
+
+ // step5: return output
+ if (1 <= nlhs) {
+ mwSize dims[2];
+ dims[0] = iStoredPixelCount;
+ dims[1] = 2;
+
+ plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
+ double* out = mxGetPr(plhs[0]);
+
+ for (int col = 0; col < iStoredPixelCount; col++) {
+ out[col] = pPixelsWeights[col].m_iIndex;
+ out[iStoredPixelCount+col] = pPixelsWeights[col].m_fWeight;
+ }
+ }
+
+ // garbage collection
+ delete[] pPixelsWeights;
+}
+
+//-----------------------------------------------------------------------------------------
+/** weights = astra_mex_projector('weights_projection', id, projection_index);
+ *
+ * Calculate the nonzero weights of all rays in a certain projection.
+ * id: identifier of the projector object as stored in the astra-library.
+ * projection_index: index of the projection angle
+ * weights: sparse matrix containing the rows of the projection matric belonging to the requested projection angle.
+ */
+void astra_mex_projector_weights_projection(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get input
+ if (nrhs < 3) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+ int iProjectionIndex = (int)(mxGetScalar(prhs[2]));
+
+ // step2: get projector
+ CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid);
+ if (!pProjector || !pProjector->isInitialized()) {
+ mexErrMsgTxt("Projector not initialized.\n");
+ return;
+ }
+
+ // step3: create output vars
+ SPixelWeight* pPixelsWheights = new SPixelWeight[pProjector->getProjectionWeightsCount(iProjectionIndex)];
+ int* piRayStoredPixelCount = new int[pProjector->getProjectionGeometry()->getDetectorCount()];
+
+ // step4: perform operation
+ pProjector->computeProjectionRayWeights(iProjectionIndex, pPixelsWheights, piRayStoredPixelCount);
+
+ // step5: return output
+ if (1 <= nlhs) {
+ // get basic values
+ int iMatrixSize = pProjector->getVolumeGeometry()->getWindowLengthX() *
+ pProjector->getVolumeGeometry()->getWindowLengthY();
+ int iDetectorCount = pProjector->getProjectionGeometry()->getDetectorCount();
+ int iTotalStoredPixelCount = 0;
+ for (int i = 0; i < iDetectorCount; i++) {
+ iTotalStoredPixelCount += piRayStoredPixelCount[i];
+ }
+
+ // create matlab sparse matrix
+ plhs[0] = mxCreateSparse(iMatrixSize, // number of rows (#pixels)
+ iDetectorCount, // number of columns (#detectors)
+ iTotalStoredPixelCount, // number of non-zero elements
+ mxREAL); // element type
+ double* values = mxGetPr(plhs[0]);
+ mwIndex* rows = mxGetIr(plhs[0]);
+ mwIndex* cols = mxGetJc(plhs[0]);
+
+ int currentBase = 0;
+ int currentIndex = 0;
+ for (int i = 0; i < iDetectorCount; i++) {
+ for (int j = 0; j < piRayStoredPixelCount[i]; j++) {
+ values[currentIndex + j] = pPixelsWheights[currentBase + j].m_fWeight;
+ rows[currentIndex + j] = pPixelsWheights[currentBase + j].m_iIndex;
+ }
+
+ currentBase += pProjector->getProjectionWeightsCount(iProjectionIndex) / pProjector->getProjectionGeometry()->getDetectorCount();
+ currentIndex += piRayStoredPixelCount[i];
+ }
+ cols[0] = piRayStoredPixelCount[0];
+ for (int j = 1; j < iDetectorCount; j++) {
+ cols[j] = cols[j-1] + piRayStoredPixelCount[j];
+ }
+ cols[iDetectorCount] = iTotalStoredPixelCount;
+ }
+
+ delete[] pPixelsWheights;
+ delete[] piRayStoredPixelCount;
+}
+
+//-----------------------------------------------------------------------------------------
+/** hit_detectors = astra_mex_projector('splat', id, col, row);
+ *
+ * Create a list of detector indices which have a nonzero contribution to the projection matrix for a pixel [row,col].
+ * id: identifier of the projector object as stored in the astra-library.
+ * col: column of the pixel
+ * row: row of the pixel
+ * hit_detectors: list of detector indices [angle_index, det_index] that are hit
+ */
+void astra_mex_projector_splat(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get input
+ if (nrhs < 4) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+ int iX = (int)(mxGetScalar(prhs[2]));
+ int iY = (int)(mxGetScalar(prhs[3]));
+
+ // step2: get projector
+ CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid);
+ if (!pProjector || !pProjector->isInitialized()) {
+ mexErrMsgTxt("Projector not initialized.\n");
+ return;
+ }
+
+ // step3: perform action
+ vector<SDetector2D> detinfo = pProjector->projectPoint(iX, iY);
+
+ // step4: output
+ if (nlhs <= 1) {
+ plhs[0] = mxCreateDoubleMatrix(detinfo.size(), // # rows
+ 2, // # cols
+ mxREAL); // datatype 32-bits
+ double* out = mxGetPr(plhs[0]);
+
+ // fill up output
+ int i = 0;
+ int x;
+ for (x = 0; x < detinfo.size(); ++x) {
+ out[i] = detinfo[x].m_iAngleIndex;
+ ++i;
+ }
+ for (x = 0; x < detinfo.size(); ++x) {
+ out[i] = detinfo[x].m_iDetectorIndex;
+ ++i;
+ }
+ }
+
+
+}
+
+//-----------------------------------------------------------------------------------------
+/** matrix_id = astra_mex_projector('matrix', id);
+ *
+ * Create an explicit projection matrix for this projector.
+ * It returns an ID usable with astra_mex_matrix().
+ * id: identifier of the projector object as stored in the astra-library.
+ */
+void astra_mex_projector_matrix(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get projector
+ CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid);
+ if (!pProjector || !pProjector->isInitialized()) {
+ mexErrMsgTxt("Projector not initialized.\n");
+ return;
+ }
+
+ CSparseMatrix* pMatrix = pProjector->getMatrix();
+ if (!pMatrix || !pMatrix->isInitialized()) {
+ mexErrMsgTxt("Couldn't initialize data object.\n");
+ delete pMatrix;
+ return;
+ }
+
+ // store data object
+ int iIndex = CMatrixManager::getSingleton().store(pMatrix);
+
+ // return data id
+ if (1 <= nlhs) {
+ plhs[0] = mxCreateDoubleScalar(iIndex);
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+/** result = astra_mex_projector('is_cuda', id);
+ *
+ * Return is the specified projector is a cuda projector.
+ * id: identifier of the projector object as stored in the astra-library.
+ */
+void astra_mex_projector_is_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+{
+ // step1: get input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ int iPid = (int)(mxGetScalar(prhs[1]));
+
+ // step2: get projector
+ CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid);
+ if (!pProjector || !pProjector->isInitialized()) {
+ mexErrMsgTxt("Projector not initialized.\n");
+ return;
+ }
+
+#ifdef ASTRA_CUDA
+ CCudaProjector2D* pCP = dynamic_cast<CCudaProjector2D*>(pProjector);
+ plhs[0] = mxCreateLogicalScalar(pCP ? 1 : 0);
+#else
+ plhs[0] = mxCreateLogicalScalar(0);
+#endif
+}
+
+
+
+//-----------------------------------------------------------------------------------------
+
+static void printHelp()
+{
+ mexPrintf("Please specify a mode of operation.\n");
+ mexPrintf("Valid modes: create, delete, clear, info, projection_geometry,\n");
+ mexPrintf(" volume_geometry, weights_single_ray, weights_projection\n");
+ mexPrintf(" splat, matrix, is_cuda\n");
+}
+
+
+//-----------------------------------------------------------------------------------------
+/**
+ * ... = astra_mex_projector(mode, ...);
+ */
+void mexFunction(int nlhs, mxArray* plhs[],
+ int nrhs, const mxArray* prhs[])
+{
+ // INPUT: Mode
+ string sMode = "";
+ if (1 <= nrhs) {
+ sMode = mex_util_get_string(prhs[0]);
+ } else {
+ printHelp();
+ return;
+ }
+
+ // SWITCH (MODE)
+ if (sMode == "create") {
+ astra_mex_projector_create(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "delete") {
+ astra_mex_projector_delete(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "clear") {
+ astra_mex_projector_clear(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "info") {
+ astra_mex_projector_info(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "projection_geometry") {
+ astra_mex_projector_projection_geometry(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "volume_geometry") {
+ astra_mex_projector_volume_geometry(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "weights_single_ray") {
+ astra_mex_projector_weights_single_ray(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "weights_projection") {
+ astra_mex_projector_weights_projection(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "splat") {
+ astra_mex_projector_splat(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "matrix") {
+ astra_mex_projector_matrix(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == "is_cuda") {
+ astra_mex_projector_is_cuda(nlhs, plhs, nrhs, prhs);
+ } else {
+ printHelp();
+ }
+ return;
+}
+
+
diff --git a/matlab/mex/astra_mex_projector_vc08.vcproj b/matlab/mex/astra_mex_projector_vc08.vcproj
new file mode 100644
index 0000000..1380061
--- /dev/null
+++ b/matlab/mex/astra_mex_projector_vc08.vcproj
@@ -0,0 +1,591 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="astra_mex_projector"
+ ProjectGUID="{4DD6056F-8EEE-4C9A-B2A9-923F01A32E97}"
+ RootNamespace="astraMatlab"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="&quot;$(MATLAB_ROOT)\extern\include\&quot;;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\;"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ BrowseInformation="1"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\astra_mex_projector_c.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/matlab/mex/astra_mex_vc08.vcproj b/matlab/mex/astra_mex_vc08.vcproj
new file mode 100644
index 0000000..58c1e0a
--- /dev/null
+++ b/matlab/mex/astra_mex_vc08.vcproj
@@ -0,0 +1,591 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="astra_mex"
+ ProjectGUID="{3FDA35E0-0D54-4663-A3E6-5ABA96F32221}"
+ RootNamespace="astraMatlab"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\lib\include\cuda;..\..\include\;"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_CUDA|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;$(CUDA_INC_PATH)&quot;;$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ PreprocessorDefinitions="ASTRA_CUDA"
+ RuntimeLibrary="3"
+ BrowseInformation="1"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib libut.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+ AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft"
+ ModuleDefinitionFile="mex.def"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+ RuntimeLibrary="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+ AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft"
+ ModuleDefinitionFile="mex.def"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\astra_mex_c.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\mexHelpFunctions.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/matlab/mex/mex.def b/matlab/mex/mex.def
new file mode 100644
index 0000000..c54c4e0
--- /dev/null
+++ b/matlab/mex/mex.def
@@ -0,0 +1 @@
+EXPORTS mexFunction \ No newline at end of file
diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
new file mode 100644
index 0000000..4105ee1
--- /dev/null
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -0,0 +1,642 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+/** \file mexHelpFunctions.cpp
+ *
+ * \brief Contains some functions for interfacing matlab with c data structures
+ */
+#include "mexHelpFunctions.h"
+
+#include "astra/SparseMatrixProjectionGeometry2D.h"
+#include "astra/FanFlatVecProjectionGeometry2D.h"
+#include "astra/AstraObjectManager.h"
+
+using namespace std;
+using namespace astra;
+
+
+//-----------------------------------------------------------------------------------------
+// get string from matlab
+std::string mex_util_get_string(const mxArray* pInput)
+{
+ if (!mxIsChar(pInput)) {
+ return "";
+ }
+ mwSize iLength = mxGetNumberOfElements(pInput) + 1;
+ char* buf = new char[iLength];
+ mxGetString(pInput, buf, iLength);
+ std::string res = std::string(buf);
+ delete[] buf;
+ return res;
+}
+
+//-----------------------------------------------------------------------------------------
+// is option
+bool isOption(std::list<std::string> lOptions, std::string sOption)
+{
+ return std::find(lOptions.begin(), lOptions.end(), sOption) != lOptions.end();
+}
+
+//-----------------------------------------------------------------------------------------
+// turn a matlab struct into a c++ map
+std::map<std::string, mxArray*> parseStruct(const mxArray* pInput)
+{
+ std::map<std::string, mxArray*> res;
+
+ // check type
+ if (!mxIsStruct(pInput)) {
+ mexErrMsgTxt("Input must be a struct.");
+ return res;
+ }
+
+ // get field names
+ int nfields = mxGetNumberOfFields(pInput);
+ for (int i = 0; i < nfields; i++) {
+ std::string sFieldName = std::string(mxGetFieldNameByNumber(pInput, i));
+ res[sFieldName] = mxGetFieldByNumber(pInput,0,i);
+ }
+ return res;
+}
+
+//-----------------------------------------------------------------------------------------
+// turn a c++ map into a matlab struct
+mxArray* buildStruct(std::map<std::string, mxArray*> mInput)
+{
+ mwSize dims[2] = {1, 1};
+ mxArray* res = mxCreateStructArray(2,dims,0,0);
+
+ for (std::map<std::string, mxArray*>::iterator it = mInput.begin(); it != mInput.end(); it++) {
+ mxAddField(res, (*it).first.c_str());
+ mxSetField(res, 0, (*it).first.c_str(), (*it).second);
+ }
+ return res;
+}
+
+//-----------------------------------------------------------------------------------------
+// parse projection geometry data
+astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray* prhs)
+{
+ // parse struct
+ std::map<string, mxArray*> mStruct = parseStruct(prhs);
+
+ // create projection geometry object
+ string type = mex_util_get_string(mStruct["type"]);
+ if (type == "parallel") {
+
+ // detector_width
+ float32 fDetWidth = 1.0f;
+ mxArray* tmp = mStruct["detector_width"];
+ if (tmp != NULL) {
+ fDetWidth = (float32)(mxGetScalar(tmp));
+ }
+
+ // detector_count
+ int iDetCount = 100;
+ tmp = mStruct["detector_count"];
+ if (tmp != NULL) {
+ iDetCount = (int)(mxGetScalar(tmp));
+ }
+
+ // angles
+ float32* pfAngles;
+ int iAngleCount;
+ tmp = mStruct["projection_angles"];
+ if (tmp != NULL) {
+ double* angleValues = mxGetPr(tmp);
+ iAngleCount = mxGetN(tmp) * mxGetM(tmp);
+ pfAngles = new float32[iAngleCount];
+ for (int i = 0; i < iAngleCount; i++) {
+ pfAngles[i] = angleValues[i];
+ }
+ } else {
+ mexErrMsgTxt("'angles' not specified, error.");
+ return NULL;
+ }
+
+ // create projection geometry
+ return new astra::CParallelProjectionGeometry2D(iAngleCount, // number of projections
+ iDetCount, // number of detectors
+ fDetWidth, // width of the detectors
+ pfAngles); // angles array
+ }
+
+ else if (type == "fanflat") {
+
+ // detector_width
+ float32 fDetWidth = 1.0f;
+ mxArray* tmp = mStruct["detector_width"];
+ if (tmp != NULL) {
+ fDetWidth = (float32)(mxGetScalar(tmp));
+ }
+
+ // detector_count
+ int iDetCount = 100;
+ tmp = mStruct["detector_count"];
+ if (tmp != NULL) {
+ iDetCount = (int)(mxGetScalar(tmp));
+ }
+
+ // angles
+ float32* pfAngles;
+ int iAngleCount;
+ tmp = mStruct["projection_angles"];
+ if (tmp != NULL) {
+ double* angleValues = mxGetPr(tmp);
+ iAngleCount = mxGetN(tmp) * mxGetM(tmp);
+ pfAngles = new float32[iAngleCount];
+ for (int i = 0; i < iAngleCount; i++) {
+ pfAngles[i] = angleValues[i];
+ }
+ } else {
+ mexErrMsgTxt("'angles' not specified, error.");
+ return NULL;
+ }
+
+ // origin_source_dist
+ int iDistOriginSource = 100;
+ tmp = mStruct["origin_source_dist"];
+ if (tmp != NULL) {
+ iDistOriginSource = (int)(mxGetScalar(tmp));
+ }
+
+ // origin_det_dist
+ int iDistOriginDet = 100;
+ tmp = mStruct["origin_det_dist"];
+ if (tmp != NULL) {
+ iDistOriginDet = (int)(mxGetScalar(tmp));
+ }
+
+ // create projection geometry
+ return new astra::CFanFlatProjectionGeometry2D(iAngleCount, // number of projections
+ iDetCount, // number of detectors
+ fDetWidth, // width of the detectors
+ pfAngles, // angles array
+ iDistOriginSource, // distance origin source
+ iDistOriginDet); // distance origin detector
+ }
+
+ else {
+ mexPrintf("Only parallel and fanflat projection geometry implemented.");
+ return NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+// create projection geometry data
+mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom)
+{
+ // temporary map to store the data for the MATLAB struct
+ std::map<std::string, mxArray*> mGeometryInfo;
+
+ // detectorCount
+ mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorCount());
+
+ if (!_pProjGeom->isOfType("fanflat_vec")) {
+ // detectorWidth
+ mGeometryInfo["DetectorWidth"] = mxCreateDoubleScalar(_pProjGeom->getDetectorWidth());
+
+ // pfProjectionAngles
+ mxArray* pAngles = mxCreateDoubleMatrix(1, _pProjGeom->getProjectionAngleCount(), mxREAL);
+ double* out = mxGetPr(pAngles);
+ for (int i = 0; i < _pProjGeom->getProjectionAngleCount(); i++) {
+ out[i] = _pProjGeom->getProjectionAngle(i);
+ }
+ mGeometryInfo["ProjectionAngles"] = pAngles;
+ }
+ else {
+ astra::CFanFlatVecProjectionGeometry2D* pVecGeom = dynamic_cast<astra::CFanFlatVecProjectionGeometry2D*>(_pProjGeom);
+ mxArray* pVectors = mxCreateDoubleMatrix(1, pVecGeom->getProjectionAngleCount()*6, mxREAL);
+ double* out = mxGetPr(pVectors);
+ int iDetCount = pVecGeom->getDetectorCount();
+ for (int i = 0; i < pVecGeom->getProjectionAngleCount(); i++) {
+ const SFanProjection* p = &pVecGeom->getProjectionVectors()[i];
+ out[6*i + 0] = p->fSrcX;
+ out[6*i + 1] = p->fSrcY;
+ out[6*i + 2] = p->fDetSX + 0.5f*iDetCount*p->fDetUX;
+ out[6*i + 3] = p->fDetSY + 0.5f*iDetCount*p->fDetUY;
+ out[6*i + 4] = p->fDetUX;
+ out[6*i + 5] = p->fDetUY;
+ }
+ mGeometryInfo["Vectors"] = pVectors;
+ }
+
+ // parallel specific options
+ if (_pProjGeom->isOfType("parallel")) {
+ // type
+ mGeometryInfo["type"] = mxCreateString("parallel");
+ }
+ // fanflat specific options
+ else if (_pProjGeom->isOfType("fanflat")) {
+ astra::CFanFlatProjectionGeometry2D* pFanFlatGeom = dynamic_cast<astra::CFanFlatProjectionGeometry2D*>(_pProjGeom);
+ // detectorCount
+ mGeometryInfo["DistanceOriginSource"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginSourceDistance());
+ // detectorWidth
+ mGeometryInfo["DistanceOriginDetector"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginDetectorDistance());
+ // type
+ mGeometryInfo["type"] = mxCreateString("fanflat");
+ }
+ else if (_pProjGeom->isOfType("sparse_matrix")) {
+ astra::CSparseMatrixProjectionGeometry2D* pSparseMatrixGeom = dynamic_cast<astra::CSparseMatrixProjectionGeometry2D*>(_pProjGeom);
+ mGeometryInfo["type"] = mxCreateString("sparse_matrix");
+ mGeometryInfo["MatrixID"] = mxCreateDoubleScalar(CMatrixManager::getSingleton().getIndex(pSparseMatrixGeom->getMatrix()));
+ }
+ else if(_pProjGeom->isOfType("fanflat_vec")) {
+ mGeometryInfo["type"] = mxCreateString("fanflat_vec");
+ }
+
+ // build and return the MATLAB struct
+ return buildStruct(mGeometryInfo);
+}
+
+//-----------------------------------------------------------------------------------------
+// parse reconstruction geometry data
+astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray* prhs)
+{
+ // parse struct
+ std::map<string, mxArray*> mStruct = parseStruct(prhs);
+
+ std::map<string, mxArray*> mOptions = parseStruct(mStruct["option"]);
+
+ // GridColCount
+ int iWindowColCount = 128;
+ mxArray* tmp = mStruct["GridColCount"];
+ if (tmp != NULL) {
+ iWindowColCount = (int)(mxGetScalar(tmp));
+ }
+
+ // GridRowCount
+ int iWindowRowCount = 128;
+ tmp = mStruct["GridRowCount"];
+ if (tmp != NULL) {
+ iWindowRowCount = (int)(mxGetScalar(tmp));
+ }
+
+ // WindowMinX
+ float32 fWindowMinX = - iWindowColCount / 2;
+ tmp = mOptions["WindowMinX"];
+ if (tmp != NULL) {
+ fWindowMinX = (float32)(mxGetScalar(tmp));
+ }
+
+ // WindowMaxX
+ float32 fWindowMaxX = iWindowColCount / 2;
+ tmp = mOptions["WindowMaxX"];
+ if (tmp != NULL) {
+ fWindowMaxX = (float32)(mxGetScalar(tmp));
+ }
+
+ // WindowMinY
+ float32 fWindowMinY = - iWindowRowCount / 2;
+ tmp = mOptions["WindowMinY"];
+ if (tmp != NULL) {
+ fWindowMinY = (float32)(mxGetScalar(tmp));
+ }
+
+ // WindowMaxX
+ float32 fWindowMaxY = iWindowRowCount / 2;
+ tmp = mOptions["WindowMaxY"];
+ if (tmp != NULL) {
+ fWindowMaxY = (float32)(mxGetScalar(tmp));
+ }
+
+ // create and return reconstruction geometry
+ return new astra::CVolumeGeometry2D(iWindowColCount, iWindowRowCount,
+ fWindowMinX, fWindowMinY,
+ fWindowMaxX, fWindowMaxY);
+}
+
+//-----------------------------------------------------------------------------------------
+// create reconstruction geometry data
+mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom)
+{
+ // temporary map to store the data for the MATLAB struct
+ std::map<std::string, mxArray*> mGeometryInfo;
+
+ // fill up map
+ mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pReconGeom->getGridColCount());
+ mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pReconGeom->getGridRowCount());
+
+ std::map<std::string, mxArray*> mGeometryOptions;
+ mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pReconGeom->getWindowMinX());
+ mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pReconGeom->getWindowMaxX());
+ mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pReconGeom->getWindowMinY());
+ mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pReconGeom->getWindowMaxY());
+
+ mGeometryInfo["option"] = buildStruct(mGeometryOptions);
+
+ // build and return the MATLAB struct
+ return buildStruct(mGeometryInfo);
+}
+
+
+//-----------------------------------------------------------------------------------------
+string matlab2string(const mxArray* pField)
+{
+ // is string?
+ if (mxIsChar(pField)) {
+ return mex_util_get_string(pField);
+ }
+
+ // is scalar?
+ if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) == 1) {
+ return boost::lexical_cast<string>(mxGetScalar(pField));
+ }
+
+ return "";
+}
+
+//-----------------------------------------------------------------------------------------
+// Options struct to xml node
+bool readOptions(XMLNode* node, const mxArray* pOptionStruct)
+{
+ // loop all fields
+ int nfields = mxGetNumberOfFields(pOptionStruct);
+ for (int i = 0; i < nfields; i++) {
+ std::string sFieldName = std::string(mxGetFieldNameByNumber(pOptionStruct, i));
+ const mxArray* pField = mxGetFieldByNumber(pOptionStruct, 0, i);
+
+ if (node->hasOption(sFieldName)) {
+ mexErrMsgTxt("Duplicate option");
+ return false;
+ }
+
+ // string or scalar
+ if (mxIsChar(pField) || mex_is_scalar(pField)) {
+ string sValue = matlab2string(pField);
+ node->addOption(sFieldName, sValue);
+ } else
+ // numerical array
+ if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
+ if (!mxIsDouble(pField)) {
+ mexErrMsgTxt("Numeric input must be double.");
+ return false;
+ }
+
+ XMLNode* listbase = node->addChildNode("Option");
+ listbase->addAttribute("key", sFieldName);
+ listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField));
+ 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;
+ } else {
+ mexErrMsgTxt("Unsupported option type");
+ return false;
+ }
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------------------
+// struct to xml node
+bool readStruct(XMLNode* root, const mxArray* pStruct)
+{
+ // loop all fields
+ int nfields = mxGetNumberOfFields(pStruct);
+ for (int i = 0; i < nfields; i++) {
+
+ // field and fieldname
+ std::string sFieldName = std::string(mxGetFieldNameByNumber(pStruct, i));
+ const mxArray* pField = mxGetFieldByNumber(pStruct, 0, i);
+
+ // string
+ if (mxIsChar(pField)) {
+ string sValue = matlab2string(pField);
+ if (sFieldName == "type") {
+ root->addAttribute("type", sValue);
+ } else {
+ delete root->addChildNode(sFieldName, sValue);
+ }
+ }
+
+ // scalar
+ if (mex_is_scalar(pField)) {
+ string sValue = matlab2string(pField);
+ delete root->addChildNode(sFieldName, sValue);
+ }
+
+ // numerical array
+ if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
+ if (!mxIsDouble(pField)) {
+ mexErrMsgTxt("Numeric input must be double.");
+ return false;
+ }
+ XMLNode* listbase = root->addChildNode(sFieldName);
+ listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField));
+ 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;
+ }
+
+
+ // not castable to a single string
+ if (mxIsStruct(pField)) {
+ if (sFieldName == "options" || sFieldName == "option" || sFieldName == "Options" || sFieldName == "Option") {
+ bool ret = readOptions(root, pField);
+ if (!ret)
+ return false;
+ } else {
+ XMLNode* newNode = root->addChildNode(sFieldName);
+ bool ret = readStruct(newNode, pField);
+ delete newNode;
+ if (!ret)
+ return false;
+ }
+ }
+
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------------------
+// turn a MATLAB struct into an XML Document
+XMLDocument* struct2XML(string rootname, const mxArray* pStruct)
+{
+ if (!mxIsStruct(pStruct)) {
+ mexErrMsgTxt("Input must be a struct.");
+ return NULL;
+ }
+
+ // create the document
+ XMLDocument* doc = XMLDocument::createDocument(rootname);
+ XMLNode* rootnode = doc->getRootNode();
+
+ // read the struct
+ bool ret = readStruct(rootnode, pStruct);
+ //doc->getRootNode()->print();
+ delete rootnode;
+
+ if (!ret) {
+ delete doc;
+ doc = 0;
+ }
+
+ return doc;
+}
+
+
+
+
+
+//-----------------------------------------------------------------------------------------
+// turn an std vector<float32> object to an mxArray
+mxArray* vectorToMxArray(std::vector<astra::float32> mInput)
+{
+ mxArray* res = mxCreateDoubleMatrix(1, mInput.size(), mxREAL);
+ double* pdData = mxGetPr(res);
+ for (unsigned int i = 0; i < mInput.size(); i++) {
+ pdData[i] = mInput[i];
+ }
+ return res;
+}
+
+//-----------------------------------------------------------------------------------------
+// turn a vector<vector<float32>> object to an mxArray
+mxArray* vector2DToMxArray(std::vector<std::vector<astra::float32> > mInput)
+{
+ unsigned int sizex = mInput.size();
+ if (sizex == 0) return mxCreateString("empty");
+ unsigned int sizey = mInput[0].size();
+
+ mxArray* res = mxCreateDoubleMatrix(sizex, sizey, mxREAL);
+ double* pdData = mxGetPr(res);
+ for (unsigned int i = 0; i < sizex; i++) {
+ for (unsigned int j = 0; j < sizey && j < mInput[i].size(); j++) {
+ pdData[j*sizex+i] = mInput[i][j];
+ }
+ }
+ return res;
+}
+
+//-----------------------------------------------------------------------------------------
+// turn a boost::any object to an mxArray
+mxArray* anyToMxArray(boost::any _any)
+{
+ if (_any.type() == typeid(std::string)) {
+ std::string str = boost::any_cast<std::string>(_any);
+ return mxCreateString(str.c_str());
+ }
+ if (_any.type() == typeid(int)) {
+ return mxCreateDoubleScalar(boost::any_cast<int>(_any));
+ }
+ if (_any.type() == typeid(float32)) {
+ return mxCreateDoubleScalar(boost::any_cast<float32>(_any));
+ }
+ if (_any.type() == typeid(std::vector<astra::float32>)) {
+ return vectorToMxArray(boost::any_cast<std::vector<float32> >(_any));
+ }
+ if (_any.type() == typeid(std::vector<std::vector<astra::float32> >)) {
+ return vector2DToMxArray(boost::any_cast<std::vector<std::vector<float32> > >(_any));
+ }
+ return NULL;
+}
+//-----------------------------------------------------------------------------------------
+// return true ig the argument is a scalar
+bool mex_is_scalar(const mxArray* pInput)
+{
+ return (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1);
+}
+
+//-----------------------------------------------------------------------------------------
+mxArray* XML2struct(astra::XMLDocument* xml)
+{
+ XMLNode* node = xml->getRootNode();
+ mxArray* str = XMLNode2struct(xml->getRootNode());
+ delete node;
+ return str;
+}
+
+//-----------------------------------------------------------------------------------------
+mxArray* XMLNode2struct(astra::XMLNode* node)
+{
+ std::map<std::string, mxArray*> mList;
+
+ // type_attribute
+ 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
+ if (subnode->hasAttribute("listsize")) {
+ cout << "lkmdsqldqsjkl" << endl;
+ cout << " " << node->getContentNumericalArray().size() << endl;
+ mList[subnode->getName()] = vectorToMxArray(node->getContentNumericalArray());
+ }
+ // string
+ else {
+ mList[subnode->getName()] = mxCreateString(subnode->getContent().c_str());
+ }
+ delete subnode;
+ }
+
+ return buildStruct(mList);
+}
+
+void get3DMatrixDims(const mxArray* x, mwSize *dims)
+{
+ const mwSize* mdims = mxGetDimensions(x);
+ mwSize dimCount = mxGetNumberOfDimensions(x);
+ if (dimCount == 1) {
+ dims[0] = mdims[0];
+ dims[1] = 1;
+ dims[2] = 1;
+ } else if (dimCount == 2) {
+ dims[0] = mdims[0];
+ dims[1] = mdims[1];
+ dims[2] = 1;
+ } else if (dimCount == 3) {
+ dims[0] = mdims[0];
+ dims[1] = mdims[1];
+ dims[2] = mdims[2];
+ } else {
+ dims[0] = 0;
+ dims[1] = 0;
+ dims[2] = 0;
+ }
+}
diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h
new file mode 100644
index 0000000..425b4ef
--- /dev/null
+++ b/matlab/mex/mexHelpFunctions.h
@@ -0,0 +1,76 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+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 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 ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#ifndef _INC_ASTRA_MEX_HELPFUNCTIONS
+#define _INC_ASTRA_MEX_HELPFUNCTIONS
+
+#include <string>
+#include <list>
+#include <iostream>
+#include <sstream>
+#include <map>
+#include <algorithm>
+#include <mex.h>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/any.hpp>
+
+#include "astra/Globals.h"
+#include "astra/Utilities.h"
+
+#include "astra/ParallelProjectionGeometry2D.h"
+#include "astra/FanFlatProjectionGeometry2D.h"
+#include "astra/VolumeGeometry2D.h"
+
+#include "astra/XMLDocument.h"
+#include "astra/XMLNode.h"
+
+std::string mex_util_get_string(const mxArray* pInput);
+bool isOption(std::list<std::string> lOptions, std::string sOption);
+
+bool mex_is_scalar(const mxArray* pInput);
+
+std::map<std::string, mxArray*> parseStruct(const mxArray* pInput);
+mxArray* buildStruct(std::map<std::string, mxArray*> mInput);
+mxArray* vectorToMxArray(std::vector<astra::float32> mInput);
+
+mxArray* anyToMxArray(boost::any _any);
+
+astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray*);
+mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D*);
+astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray*);
+mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom);
+
+astra::XMLDocument* struct2XML(string rootname, const mxArray* pStruct);
+
+mxArray* XML2struct(astra::XMLDocument* xml);
+mxArray* XMLNode2struct(astra::XMLNode* xml);
+
+void get3DMatrixDims(const mxArray* x, mwSize *dims);
+
+#endif
diff --git a/matlab/tools/ROIselectfull.m b/matlab/tools/ROIselectfull.m
new file mode 100644
index 0000000..a50c979
--- /dev/null
+++ b/matlab/tools/ROIselectfull.m
@@ -0,0 +1,18 @@
+function V_out = ROIselectfull(input, ROI)
+
+ s1 = size(input,1);
+ s2 = size(input,2);
+ [x y] = meshgrid(-(s2-1)/2:(s2-1)/2,(s1-1)/2:-1:-(s1-1)/2);
+ A = Afstand(x,y,0,0);
+
+ V_out = zeros(size(input));
+ for slice = 1:size(input,3);
+ V = input(:,:,slice);
+ V(A > ROI/2) = 0;
+ V_out(:,:,slice) = V;
+ end
+end
+
+function A = Afstand(x1,y1,x2,y2)
+ A = sqrt((x1-x2).^2+(y1-y2).^2);
+end \ No newline at end of file
diff --git a/matlab/tools/astra_add_noise_to_sino.m b/matlab/tools/astra_add_noise_to_sino.m
new file mode 100644
index 0000000..a262f49
--- /dev/null
+++ b/matlab/tools/astra_add_noise_to_sino.m
@@ -0,0 +1,47 @@
+function sinogram_out = astra_add_noise_to_sino(sinogram_in,I0)
+
+%--------------------------------------------------------------------------
+% sinogram_out = astra_add_noise_to_sino(sinogram_in,I0)
+%
+% Add poisson noise to a sinogram.
+%
+% sinogram_in: input sinogram, can be either MATLAB-data or an
+% astra-identifier. In the latter case, this operation is inplace and the
+% result will also be stored in this data object.
+% I0: background intensity, used to set noise level, lower equals more
+% noise
+% sinogram_out: output sinogram in MATLAB-data.
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+if numel(sinogram_in) == 1
+ sinogramRaw = astra_mex_data2d('get', sinogram_in);
+else
+ sinogramRaw = sinogram_in;
+end
+
+% scale to [0,1]
+max_sinogramRaw = max(sinogramRaw(:));
+sinogramRawScaled = sinogramRaw ./ max_sinogramRaw;
+% to detector count
+sinogramCT = I0 * exp(-sinogramRawScaled);
+% add poison noise
+sinogramCT_A = sinogramCT * 1e-12;
+sinogramCT_B = double(imnoise(sinogramCT_A, 'poisson'));
+sinogramCT_C = sinogramCT_B * 1e12;
+% to density
+sinogramCT_D = sinogramCT_C / I0;
+sinogram_out = -max_sinogramRaw * log(sinogramCT_D);
+
+if numel(sinogram_in) == 1
+ astra_mex_data2d('store', sinogram_in, sinogram_out);
+end
diff --git a/matlab/tools/astra_clear.m b/matlab/tools/astra_clear.m
new file mode 100644
index 0000000..d42e395
--- /dev/null
+++ b/matlab/tools/astra_clear.m
@@ -0,0 +1,19 @@
+%--------------------------------------------------------------------------
+% Clears and frees memory of all objects (data, projectors, algorithms)
+% currently in the astra-library.
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+astra_mex_data2d('clear');
+astra_mex_data3d('clear');
+astra_mex_algorithm('clear');
+astra_mex_projector('clear');
diff --git a/matlab/tools/astra_create_backprojection.m b/matlab/tools/astra_create_backprojection.m
new file mode 100644
index 0000000..7f0b02f
--- /dev/null
+++ b/matlab/tools/astra_create_backprojection.m
@@ -0,0 +1,63 @@
+function [vol_id, vol] = astra_create_backprojection(data, proj_id)
+
+%--------------------------------------------------------------------------
+% [vol_id, vol] = astra_create_backprojection(data, proj_id)
+%
+% Create a CPU based back projection.
+%
+% data: input sinogram, can be either MATLAB-data or an astra-identifier.
+% proj_id: identifier of the projector as it is stored in the astra-library
+% vol_id: identifier of the volume data object as it is now stored in the astra-library.
+% vol: MATLAB data version of the volume
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+% get projection geometry
+proj_geom = astra_mex_projector('projection_geometry', proj_id);
+vol_geom = astra_mex_projector('volume_geometry', proj_id);
+
+% store sinogram
+if (numel(data) > 1)
+ sino_id = astra_mex_data2d('create','-sino', proj_geom, data);
+else
+ sino_id = data;
+end
+
+% store volume
+vol_id = astra_mex_data2d('create','-vol', vol_geom, 0);
+
+if astra_mex_projector('is_cuda', proj_id)
+ cfg = astra_struct('BP_CUDA');
+else
+ cfg = astra_struct('BP');
+end
+
+cfg.ProjectorId = proj_id;
+cfg.ProjectionDataId = sino_id;
+cfg.ReconstructionDataId = vol_id;
+
+% create backprojection
+alg_id = astra_mex_algorithm('create', cfg);
+astra_mex_algorithm('iterate', alg_id);
+astra_mex_algorithm('delete', alg_id);
+
+if (numel(data) > 1)
+ astra_mex_data2d('delete', sino_id);
+end
+
+if nargout >= 2
+ vol = astra_mex_data2d('get',vol_id);
+end
+
+
+
diff --git a/matlab/tools/astra_create_backprojection3d_cuda.m b/matlab/tools/astra_create_backprojection3d_cuda.m
new file mode 100644
index 0000000..afa41db
--- /dev/null
+++ b/matlab/tools/astra_create_backprojection3d_cuda.m
@@ -0,0 +1,54 @@
+function [vol_id, vol] = astra_create_backprojection3d_cuda(data, proj_geom, vol_geom)
+
+%--------------------------------------------------------------------------
+% [vol_id, vol] = astra_create_backprojection3d_cuda(data, proj_geom, vol_geom)
+%
+% Create a GPU based backprojection.
+%
+% data: input projection data, can be either MATLAB-data or an astra-identifier.
+% proj_geom: MATLAB struct containing the projection geometry.
+% vol_geom: MATLAB struct containing the volume geometry.
+% vol_id: identifier of the volume data object as it is now stored in
+% the astra-library.
+% vol: MATLAB data version of the volume.
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+% store projection data
+if (numel(data) > 1)
+ sino_id = astra_mex_data3d('create','-proj3d', proj_geom, data);
+else
+ sino_id = data;
+end
+
+% store volume
+vol_id = astra_mex_data3d('create','-vol', vol_geom, 0);
+
+% create sinogram
+cfg = astra_struct('BP3D_CUDA');
+cfg.ProjectionDataId = sino_id;
+cfg.ReconstructionDataId = vol_id;
+alg_id = astra_mex_algorithm('create', cfg);
+astra_mex_algorithm('iterate', alg_id);
+astra_mex_algorithm('delete', alg_id);
+
+if (numel(data) > 1)
+ astra_mex_data3d('delete', sino_id);
+end
+
+if nargout >= 2
+ vol = astra_mex_data3d('get',vol_id);
+end
+
+
+
diff --git a/matlab/tools/astra_create_backprojection_cuda.m b/matlab/tools/astra_create_backprojection_cuda.m
new file mode 100644
index 0000000..cef7864
--- /dev/null
+++ b/matlab/tools/astra_create_backprojection_cuda.m
@@ -0,0 +1,39 @@
+function backProj = astra_create_backprojection_cuda(sinogramData, proj_geom, vol_geom)
+ %--------------------------------------------------------------------------
+ % backProj = astra_create_backprojection_cuda(sinogramData, proj_geom, vol_geom)
+ %
+ % Creates a CUDA-based simple backprojection
+ %
+ % sinogramData: 2D matrix with projections stored row-based
+ % theta: projection angles, length should be equal to the number of rows in
+ % sinogramData
+ % reconstructionSize: vector with length 2 with the row and column count of
+ % the reconstruction image
+ % backProj: 2D back projection from sinogram data
+ %--------------------------------------------------------------------------
+ %------------------------------------------------------------------------
+ % This file is part of the
+ % All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+ %
+ % Copyright: iMinds-Vision Lab, University of Antwerp
+ % License: Open Source under GPLv3
+ % Contact: mailto:astra@ua.ac.be
+ % Website: http://astra.ua.ac.be
+ %------------------------------------------------------------------------
+ % $Id$
+
+ recon_id = astra_mex_data2d('create', '-vol', vol_geom, 0);
+ sinogram_id = astra_mex_data2d('create', '-sino', proj_geom, sinogramData);
+
+ cfg = astra_struct('BP_CUDA');
+ cfg.ProjectionDataId = sinogram_id;
+ cfg.ReconstructionDataId = recon_id;
+
+ alg_id = astra_mex_algorithm('create', cfg);
+ astra_mex_algorithm('run', alg_id);
+ backProj = astra_mex_data2d('get', recon_id);
+
+ astra_mex_data2d('delete', sinogram_id);
+ astra_mex_data2d('delete', recon_id);
+ astra_mex_algorithm('delete', alg_id);
+end
diff --git a/matlab/tools/astra_create_fbp_reconstruction.m b/matlab/tools/astra_create_fbp_reconstruction.m
new file mode 100644
index 0000000..4456f9c
--- /dev/null
+++ b/matlab/tools/astra_create_fbp_reconstruction.m
@@ -0,0 +1,23 @@
+function [FBP_id, FBP] = astra_create_fbp_reconstruction(sinogram, proj_id)
+
+proj_geom = astra_mex_projector('projection_geometry', proj_id);
+vol_geom = astra_mex_projector('volume_geometry', proj_id);
+
+if numel(sinogram) == 1
+ sinogram_id = sinogram;
+else
+ sinogram_id = astra_mex_data2d('create', '-sino', proj_geom, sinogram);
+end
+
+FBP_id = astra_mex_data2d('create','-vol',vol_geom, 0);
+
+cfg = astra_struct('FBP_CUDA');
+cfg.ProjectionDataId = sinogram_id;
+cfg.ReconstructionDataId = FBP_id;
+cfg.FilterType = 'Ram-Lak';
+cfg.ProjectorId = proj_id;
+cfg.Options.GPUindex = 0;
+alg_id = astra_mex_algorithm('create', cfg);
+astra_mex_algorithm('run', alg_id);
+
+FBP = astra_mex_data2d('get', FBP_id);
diff --git a/matlab/tools/astra_create_proj_geom.m b/matlab/tools/astra_create_proj_geom.m
new file mode 100644
index 0000000..dbf0464
--- /dev/null
+++ b/matlab/tools/astra_create_proj_geom.m
@@ -0,0 +1,204 @@
+function proj_geom = astra_create_proj_geom(type, varargin)
+
+%--------------------------------------------------------------------------
+% proj_geom = astra_create_proj_geom('parallel', det_width, det_count, angles)
+%
+% Create a 2D parallel beam geometry. See the API for more information.
+% det_width: distance between two adjacent detectors
+% det_count: number of detectors in a single projection
+% angles: projection angles in radians, should be between -pi/4 and 7pi/4
+% proj_geom: MATLAB struct containing all information of the geometry
+%--------------------------------------------------------------------------
+% proj_geom = astra_create_proj_geom('parallel3d', det_spacing_x, det_spacing_y, det_row_count, det_col_count, angles)
+%
+% Create a 3D parallel beam geometry. See the API for more information.
+% det_spacing_x: distance between two horizontally adjacent detectors
+% det_spacing_y: distance between two vertically adjacent detectors
+% det_row_count: number of detector rows in a single projection
+% det_col_count: number of detector columns in a single projection
+% angles: projection angles in radians, should be between -pi/4 and 7pi/4
+% proj_geom: MATLAB struct containing all information of the geometry
+%--------------------------------------------------------------------------
+% proj_geom = astra_create_proj_geom('fanflat', det_width, det_count, angles, source_origin, origin_det)
+%
+% Create a 2D flat fan beam geometry. See the API for more information.
+% det_width: distance between two adjacent detectors
+% det_count: number of detectors in a single projection
+% angles: projection angles in radians, should be between -pi/4 and 7pi/4
+% source_origin: distance between the source and the center of rotation
+% origin_det: distance between the center of rotation and the detector array
+% proj_geom: MATLAB struct containing all information of the geometry
+%--------------------------------------------------------------------------
+% proj_geom = astra_create_proj_geom('fanflat_vec', det_count, vectors)
+%
+% Create a 2D flat fan beam geometry specified by 2D vectors.
+% See the API for more information.
+% det_count: number of detectors in a single projection
+% vectors: a matrix containing the actual geometry. Each row corresponds
+% to a single projection, and consists of:
+% ( srcX, srcY, dX, dY, uX, uY )
+% src: the ray source
+% d : the center of the detector
+% u : the vector from detector pixel 0 to 1
+% proj_geom: MATLAB struct containing all information of the geometry
+%--------------------------------------------------------------------------
+% proj_geom = astra_create_proj_geom('cone', det_spacing_x, det_spacing_y, det_row_count, det_col_count, angles, source_origin, origin_det)
+%
+% Create a 3D cone beam geometry. See the API for more information.
+% det_spacing_x: distance between two horizontally adjacent detectors
+% det_spacing_y: distance between two vertically adjacent detectors
+% det_row_count: number of detector rows in a single projection
+% det_col_count: number of detector columns in a single projection
+% angles: projection angles in radians, should be between -pi/4 and 7pi/4
+% source_origin: distance between the source and the center of rotation
+% origin_det: distance between the center of rotation and the detector array
+% proj_geom: MATLAB struct containing all information of the geometry
+%--------------------------------------------------------------------------
+% proj_geom = astra_create_proj_geom('cone_vec', det_row_count, det_col_count, vectors)
+%
+% Create a 3D cone beam geometry specified by 3D vectors.
+% See the API for more information.
+% det_row_count: number of detector rows in a single projection
+% det_col_count: number of detector columns in a single projection
+% vectors: a matrix containing the actual geometry. Each row corresponds
+% to a single projection, and consists of:
+% ( srcX, srcY, srcZ, dX, dY, dZ, uX, uY, uZ, vX, vY, vZ )
+% src: the ray source
+% d : the center of the detector
+% u : the vector from detector pixel (0,0) to (0,1)
+% v : the vector from detector pixel (0,0) to (1,0)
+% proj_geom: MATLAB struct containing all information of the geometry
+%--------------------------------------------------------------------------
+% proj_geom = astra_create_proj_geom('parallel3d_vec', det_row_count, det_col_count, vectors)
+%
+% Create a 3D parallel beam geometry specified by 3D vectors.
+% See the API for more information.
+% det_row_count: number of detector rows in a single projection
+% det_col_count: number of detector columns in a single projection
+% vectors: a matrix containing the actual geometry. Each row corresponds
+% to a single projection, and consists of:
+% ( rayX, rayY, rayZ, dX, dY, dZ, uX, uY, uZ, vX, vY, vZ )
+% ray: the ray direction
+% d : the center of the detector
+% u : the vector from detector pixel (0,0) to (0,1)
+% v : the vector from detector pixel (0,0) to (1,0)
+% proj_geom: MATLAB struct containing all information of the geometry
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+if strcmp(type,'parallel')
+ if numel(varargin) < 3
+ error('not enough variables: astra_create_proj_geom(parallel, detector_spacing, det_count, angles)');
+ end
+ proj_geom = struct( ...
+ 'type', 'parallel', ...
+ 'DetectorWidth', varargin{1}, ...
+ 'DetectorCount', varargin{2}, ...
+ 'ProjectionAngles', varargin{3} ...
+ );
+
+elseif strcmp(type,'fanflat')
+ if numel(varargin) < 5
+ error('not enough variables: astra_create_proj_geom(fanflat, det_width, det_count, angles, source_origin, source_det)');
+ end
+ proj_geom = struct( ...
+ 'type', 'fanflat', ...
+ 'DetectorWidth', varargin{1}, ...
+ 'DetectorCount', varargin{2}, ...
+ 'ProjectionAngles', varargin{3}, ...
+ 'DistanceOriginSource', varargin{4}, ...
+ 'DistanceOriginDetector', varargin{5} ...
+ );
+
+elseif strcmp(type,'fanflat_vec')
+ if numel(varargin) < 2
+ error('not enough variables: astra_create_proj_geom(fanflat_vec, det_count, V')
+ end
+ if size(varargin{2}, 2) ~= 6
+ error('V should be a Nx6 matrix, with N the number of projections')
+ end
+ proj_geom = struct( ...
+ 'type', 'fanflat_vec', ...
+ 'DetectorCount', varargin{1}, ...
+ 'Vectors', varargin{2} ...
+ );
+
+elseif strcmp(type,'parallel3d')
+ if numel(varargin) < 5
+ error('not enough variables: astra_create_proj_geom(parallel3d, detector_spacing_x, detector_spacing_y, det_row_count, det_col_count, angles)');
+ end
+ proj_geom = struct( ...
+ 'type', 'parallel3d', ...
+ 'DetectorSpacingX', varargin{1}, ...
+ 'DetectorSpacingY', varargin{2}, ...
+ 'DetectorRowCount', varargin{3}, ...
+ 'DetectorColCount', varargin{4}, ...
+ 'ProjectionAngles', varargin{5} ...
+ );
+elseif strcmp(type,'cone')
+ if numel(varargin) < 7
+ error('not enough variables: astra_create_proj_geom(cone, detector_spacing_x, detector_spacing_y, det_row_count, det_col_count, angles, source_origin, source_det)');
+ end
+ proj_geom = struct( ...
+ 'type', 'cone', ...
+ 'DetectorSpacingX', varargin{1}, ...
+ 'DetectorSpacingY', varargin{2}, ...
+ 'DetectorRowCount', varargin{3}, ...
+ 'DetectorColCount', varargin{4}, ...
+ 'ProjectionAngles', varargin{5}, ...
+ 'DistanceOriginSource', varargin{6}, ...
+ 'DistanceOriginDetector',varargin{7} ...
+ );
+elseif strcmp(type,'cone_vec')
+ if numel(varargin) < 3
+ error('not enough variables: astra_create_proj_geom(cone_vec, det_row_count, det_col_count, V')
+ end
+ if size(varargin{3}, 2) ~= 12
+ error('V should be a Nx12 matrix, with N the number of projections')
+ end
+ proj_geom = struct( ...
+ 'type', 'cone_vec', ...
+ 'DetectorRowCount', varargin{1}, ...
+ 'DetectorColCount', varargin{2}, ...
+ 'Vectors', varargin{3} ...
+ );
+elseif strcmp(type,'parallel3d_vec')
+ if numel(varargin) < 3
+ error('not enough variables: astra_create_proj_geom(parallel3d_vec, det_row_count, det_col_count, V')
+ end
+ if size(varargin{3}, 2) ~= 12
+ error('V should be a Nx12 matrix, with N the number of projections')
+ end
+ proj_geom = struct( ...
+ 'type', 'parallel3d_vec', ...
+ 'DetectorRowCount', varargin{1}, ...
+ 'DetectorColCount', varargin{2}, ...
+ 'Vectors', varargin{3} ...
+ );
+elseif strcmp(type,'sparse_matrix')
+ if numel(varargin) < 3
+ error('not enough variables: astra_create_proj_geom(sparse_matrix, det_width, det_count, angles, matrix_id)')
+ end
+ proj_geom = struct( ...
+ 'type', 'sparse_matrix', ...
+ 'DetectorWidth', varargin{1}, ...
+ 'DetectorCount', varargin{2}, ...
+ 'ProjectionAngles', varargin{3}, ...
+ 'MatrixID', varargin{4} ...
+ );
+
+else
+ disp(['Error: unknown type ' type]);
+ proj_geom = struct();
+end
+
diff --git a/matlab/tools/astra_create_projector.m b/matlab/tools/astra_create_projector.m
new file mode 100644
index 0000000..f773d0d
--- /dev/null
+++ b/matlab/tools/astra_create_projector.m
@@ -0,0 +1,50 @@
+function proj_id = astra_create_projector(type, proj_geom, vol_geom)
+
+%--------------------------------------------------------------------------
+% proj_id = astra_create_projector(type, proj_geom, vol_geom)
+%
+% Create a new projector object based on projection and volume geometry.
+% Used when the default values of each projector are sufficient.
+%
+% type: type of the projector. 'blob', 'line', 'linear' 'strip', ... See API for more information.
+% proj_geom: MATLAB struct containing the projection geometry.
+% vol_geom: MATLAB struct containing the volume geometry.
+% proj_id: identifier of the projector as it is now stored in the astra-library.
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+cfg_proj = astra_struct(type);
+cfg_proj.ProjectionGeometry = proj_geom;
+cfg_proj.VolumeGeometry = vol_geom;
+
+if strcmp(type,'blob')
+ % Blob options
+ blob_size = 2;
+ blob_sample_rate = 0.01;
+ blob_values = kaiserBessel(2, 10.4, blob_size, 0:blob_sample_rate:blob_size);
+ cfg_proj.Kernel.KernelSize = blob_size;
+ cfg_proj.Kernel.SampleRate = blob_sample_rate;
+ cfg_proj.Kernel.SampleCount = length(blob_values);
+ cfg_proj.Kernel.KernelValues = blob_values;
+end
+
+if strcmp(type,'linear3d') || strcmp(type,'linearcone') || strcmp(type,'cuda3d')
+ proj_id = astra_mex_projector3d('create', cfg_proj);
+else
+ proj_id = astra_mex_projector('create', cfg_proj);
+end
+
+
+
+
+
diff --git a/matlab/tools/astra_create_reconstruction.m b/matlab/tools/astra_create_reconstruction.m
new file mode 100644
index 0000000..15e452c
--- /dev/null
+++ b/matlab/tools/astra_create_reconstruction.m
@@ -0,0 +1,97 @@
+function [recon_id, recon] = astra_create_reconstruction(rec_type, proj_id, sinogram, iterations, use_mask, mask, use_minc, minc, use_maxc, maxc)
+
+%--------------------------------------------------------------------------
+% [recon_id, recon] = astra_create_reconstruction(rec_type, proj_id, sinogram, iterations, use_mask, mask, use_minc, minc, use_maxc, maxc)
+%
+% Create a CPU based iterative reconstruction.
+%
+% rec_type: reconstruction type, 'ART', 'SART' 'SIRT' or 'CGLS', not all options are adjustable
+% proj_id: identifier of the projector as it is stored in the astra-library
+% sinogram: sinogram data OR sinogram identifier
+% iterations: number of iterations to perform
+% use_mask: use a reconstrucionmask? 'yes' or 'no'
+% mask: mask data OR mask identifier.
+% use_minc: use a minimum constraint? 'yes' or 'no'
+% minc: minimum constraint value
+% use_maxc: use a maximum constraint? 'yes' or 'no'
+% maxc: maximum constraint value
+% recon_id: identifier of the reconstruction data object as it is now stored in the astra-library
+% recon: MATLAB data version of the reconstruction
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+if nargin <= 4
+ use_mask = 'no';
+ mask = [];
+ use_minc = 'no';
+ minc = 0;
+ use_maxc = 'no';
+ maxc = 255;
+end
+
+if nargin <= 6
+ use_minc = 'no';
+ minc = 0;
+ use_maxc = 'no';
+ maxc = 255;
+end
+
+if numel(sinogram) == 1
+ sinogram_id = sinogram;
+else
+ proj_geom = astra_mex_projector('projection_geometry', proj_id);
+ sinogram_id = astra_mex_data2d('create', '-sino', proj_geom, sinogram);
+end
+
+% create reconstruction object
+vol_geom = astra_mex_projector('volume_geometry', proj_id);
+recon_id = astra_mex_data2d('create', '-vol', vol_geom, 0);
+
+% configure
+cfg = astra_struct(rec_type);
+cfg.ProjectorId = proj_id;
+cfg.ProjectionDataId = sinogram_id;
+cfg.ReconstructionDataId = recon_id;
+if strcmp(use_mask,'yes')
+ if numel(mask) == 1
+ mask_id = mask;
+ else
+ mask_id = astra_mex_data2d('create', '-vol', vol_geom, mask);
+ end
+ cfg.options.ReconstructionMaskId = mask_id;
+end
+cfg.options.UseMinConstraint = use_minc;
+cfg.options.MinConstraintValue = minc;
+cfg.options.UseMaxConstraint = use_maxc;
+cfg.options.MaxConstraintValue = maxc;
+cfg.options.ProjectionOrder = 'random';
+alg_id = astra_mex_algorithm('create', cfg);
+
+% iterate
+astra_mex_algorithm('iterate', alg_id, iterations);
+
+% return object
+recon = astra_mex_data2d('get', recon_id);
+
+% garbage collection
+astra_mex_algorithm('delete', alg_id);
+if numel(sinogram) ~= 1
+ astra_mex_data2d('delete', sinogram_id);
+end
+
+if strcmp(use_mask,'yes')
+ if numel(mask) ~= 1
+ astra_mex_data2d('delete', mask_id);
+ end
+end
+
diff --git a/matlab/tools/astra_create_reconstruction_cuda.m b/matlab/tools/astra_create_reconstruction_cuda.m
new file mode 100644
index 0000000..b428eb5
--- /dev/null
+++ b/matlab/tools/astra_create_reconstruction_cuda.m
@@ -0,0 +1,80 @@
+function [recon_id, recon] = astra_create_reconstruction_cuda(rec_type, proj_geom, vol_geom, sinogram, iterations, use_mask, mask, use_minc, minc, use_maxc, maxc)
+
+%--------------------------------------------------------------------------
+% [recon_id, recon] = astra_create_reconstruction_cuda(rec_type, proj_geom, vol_geom, sinogram, iterations, use_mask, mask, use_minc, minc, use_maxc, maxc)
+%
+% Create a GPU based iterative reconstruction.
+%
+% rec_type: reconstruction type, only 'SIRT_CUDA' for now
+% proj_geom: projection geometry struct
+% vol_geom: volume geometry struct
+% sinogram: sinogram data OR sinogram identifier
+% iterations: number of iterations to perform
+% use_mask: use a reconstrucionmask? 'yes' or 'no'
+% mask: mask data OR mask identifier.
+% use_minc: use a minimum constraint? 'yes' or 'no'
+% minc: minimum constraint value
+% use_maxc: use a maximum constraint? 'yes' or 'no'
+% maxc: maximum constraint value
+% recon_id: identifier of the reconstruction data object as it is now stored in the astra-library
+% recon: MATLAB data version of the reconstruction
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+if numel(sinogram) == 1
+ sinogram_id = sinogram;
+else
+ sinogram_id = astra_mex_data2d('create', '-sino', proj_geom, sinogram);
+end
+
+% create reconstruction object
+recon_id = astra_mex_data2d('create', '-vol', vol_geom, 0);
+
+% configure
+cfg = astra_struct('SIRT_CUDA');
+cfg.ProjectionGeometry = proj_geom;
+cfg.ReconstructionGeometry = vol_geom;
+cfg.ProjectionDataId = sinogram_id;
+cfg.ReconstructionDataId = recon_id;
+if strcmp(use_mask,'yes')
+ if numel(mask) == 1
+ mask_id = mask;
+ else
+ mask_id = astra_mex_data2d('create', '-vol', vol_geom, mask);
+ end
+ cfg.options.ReconstructionMaskId = mask_id;
+end
+cfg.options.UseMinConstraint = use_minc;
+cfg.options.MinConstraintValue = minc;
+cfg.options.UseMaxConstraint = use_maxc;
+cfg.options.MaxConstraintValue = maxc;
+alg_id = astra_mex_algorithm('create', cfg);
+
+% iterate
+astra_mex_algorithm('iterate', alg_id, iterations);
+
+% return object
+recon = astra_mex_data2d('get', recon_id);
+
+% garbage collection
+astra_mex_algorithm('delete', alg_id);
+if numel(sinogram) ~= 1
+ astra_mex_data2d('delete', sinogram_id);
+end
+
+if strcmp(use_mask,'yes')
+ if numel(mask) ~= 1
+ astra_mex_data2d('delete', mask_id);
+ end
+end
+
diff --git a/matlab/tools/astra_create_sino.m b/matlab/tools/astra_create_sino.m
new file mode 100644
index 0000000..4771bd6
--- /dev/null
+++ b/matlab/tools/astra_create_sino.m
@@ -0,0 +1,63 @@
+function [sino_id, sino] = astra_create_sino(data, proj_id)
+
+%--------------------------------------------------------------------------
+% [sino_id, sino] = astra_create_sino(data, proj_id)
+%
+% Create a CPU based forward projection.
+%
+% data: input volume, can be either MATLAB-data or an astra-identifier.
+% proj_id: identifier of the projector as it is stored in the astra-library
+% sino_id: identifier of the sinogram data object as it is now stored in the astra-library.
+% sino: MATLAB data version of the sinogram
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+% get projection geometry
+proj_geom = astra_mex_projector('projection_geometry', proj_id);
+vol_geom = astra_mex_projector('volume_geometry', proj_id);
+
+% store volume
+if (numel(data) > 1)
+ volume_id = astra_mex_data2d('create','-vol', vol_geom, data);
+else
+ volume_id = data;
+end
+
+% store sino
+sino_id = astra_mex_data2d('create','-sino', proj_geom, 0);
+
+if astra_mex_projector('is_cuda', proj_id)
+ cfg = astra_struct('FP_CUDA');
+else
+ cfg = astra_struct('FP');
+end
+
+cfg.ProjectorId = proj_id;
+cfg.ProjectionDataId = sino_id;
+cfg.VolumeDataId = volume_id;
+
+% create sinogram
+alg_id = astra_mex_algorithm('create', cfg);
+astra_mex_algorithm('iterate', alg_id);
+astra_mex_algorithm('delete', alg_id);
+
+if (numel(data) > 1)
+ astra_mex_data2d('delete', volume_id);
+end
+
+if nargout >= 2
+ sino = astra_mex_data2d('get',sino_id);
+end
+
+
+
diff --git a/matlab/tools/astra_create_sino3d_cuda.m b/matlab/tools/astra_create_sino3d_cuda.m
new file mode 100644
index 0000000..ef22ebe
--- /dev/null
+++ b/matlab/tools/astra_create_sino3d_cuda.m
@@ -0,0 +1,54 @@
+function [sino_id, sino] = astra_create_sino3d_cuda(data, proj_geom, vol_geom)
+
+%--------------------------------------------------------------------------
+% [sino_id, sino] = astra_create_sino3d_cuda(data, proj_geom, vol_geom)
+%
+% Create a GPU based forward projection.
+%
+% data: input volume, can be either MATLAB-data or an astra-identifier.
+% proj_geom: MATLAB struct containing the projection geometry.
+% vol_geom: MATLAB struct containing the volume geometry.
+% sino_id: identifier of the sinogram data object as it is now stored in
+% the astra-library.
+% sino: MATLAB data version of the sinogram.
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+% store volume
+if (numel(data) > 1)
+ volume_id = astra_mex_data3d('create','-vol', vol_geom, data);
+else
+ volume_id = data;
+end
+
+% store sino
+sino_id = astra_mex_data3d('create','-sino', proj_geom, 0);
+
+% create sinogram
+cfg = astra_struct('FP3D_CUDA');
+cfg.ProjectionDataId = sino_id;
+cfg.VolumeDataId = volume_id;
+alg_id = astra_mex_algorithm('create', cfg);
+astra_mex_algorithm('iterate', alg_id);
+astra_mex_algorithm('delete', alg_id);
+
+if (numel(data) > 1)
+ astra_mex_data3d('delete', volume_id);
+end
+
+if nargout >= 2
+ sino = astra_mex_data3d('get',sino_id);
+end
+
+
+
diff --git a/matlab/tools/astra_create_sino_cuda.m b/matlab/tools/astra_create_sino_cuda.m
new file mode 100644
index 0000000..82bda7c
--- /dev/null
+++ b/matlab/tools/astra_create_sino_cuda.m
@@ -0,0 +1,58 @@
+function [sino_id, sino] = astra_create_sino_cuda(data, proj_geom, vol_geom, gpu_index)
+
+%--------------------------------------------------------------------------
+% [sino_id, sino] = astra_create_sino_cuda(data, proj_geom, vol_geom, gpu_index)
+%
+% Create a GPU based forward projection.
+%
+% data: input volume, can be either MATLAB-data or an astra-identifier.
+% proj_geom: MATLAB struct containing the projection geometry.
+% vol_geom: MATLAB struct containing the volume geometry.
+% gpu_index: the index of the GPU to use (optional).
+% sino_id: identifier of the sinogram data object as it is now stored in
+% the astra-library.
+% sino: MATLAB data version of the sinogram.
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+% store volume
+if (numel(data) > 1)
+ volume_id = astra_mex_data2d('create','-vol', vol_geom, data);
+else
+ volume_id = data;
+end
+
+% store sino
+sino_id = astra_mex_data2d('create','-sino', proj_geom, 0);
+
+% create sinogram
+cfg = astra_struct('FP_CUDA');
+cfg.ProjectionDataId = sino_id;
+cfg.VolumeDataId = volume_id;
+if nargin > 3
+ cfg.option.GPUindex = gpu_index;
+end
+alg_id = astra_mex_algorithm('create', cfg);
+astra_mex_algorithm('iterate', alg_id);
+astra_mex_algorithm('delete', alg_id);
+
+if (numel(data) > 1)
+ astra_mex_data2d('delete', volume_id);
+end
+
+if nargout >= 2
+ sino = astra_mex_data2d('get',sino_id);
+end
+
+
+
diff --git a/matlab/tools/astra_create_sino_gpu.m b/matlab/tools/astra_create_sino_gpu.m
new file mode 100644
index 0000000..95a3b09
--- /dev/null
+++ b/matlab/tools/astra_create_sino_gpu.m
@@ -0,0 +1,58 @@
+function [sino_id, sino] = astra_create_sino_gpu(data, proj_geom, vol_geom, gpu_index)
+
+%--------------------------------------------------------------------------
+% [sino_id, sino] = astra_create_sino_gpu(data, proj_geom, vol_geom, gpu_index)
+%
+% Create a GPU based forward projection.
+%
+% data: input volume, can be either MATLAB-data or an astra-identifier.
+% proj_geom: MATLAB struct containing the projection geometry.
+% vol_geom: MATLAB struct containing the volume geometry.
+% gpu_index: the index of the GPU to use (optional).
+% sino_id: identifier of the sinogram data object as it is now stored in
+% the astra-library.
+% sino: MATLAB data version of the sinogram.
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+% store volume
+if (numel(data) > 1)
+ volume_id = astra_mex_data2d('create','-vol', vol_geom, data);
+else
+ volume_id = data;
+end
+
+% store sino
+sino_id = astra_mex_data2d('create','-sino', proj_geom, 0);
+
+% create sinogram
+cfg = astra_struct('FP_CUDA');
+cfg.ProjectionDataId = sino_id;
+cfg.VolumeDataId = volume_id;
+if nargin > 3
+ cfg.option.GPUindex = gpu_index;
+end
+alg_id = astra_mex_algorithm('create', cfg);
+astra_mex_algorithm('iterate', alg_id);
+astra_mex_algorithm('delete', alg_id);
+
+if (numel(data) > 1)
+ astra_mex_data2d('delete', volume_id);
+end
+
+if nargout >= 2
+ sino = astra_mex_data2d('get',sino_id);
+end
+
+
+
diff --git a/matlab/tools/astra_create_sino_sampling.m b/matlab/tools/astra_create_sino_sampling.m
new file mode 100644
index 0000000..6b86d61
--- /dev/null
+++ b/matlab/tools/astra_create_sino_sampling.m
@@ -0,0 +1,59 @@
+function [sino_id, sino] = astra_create_sino_sampling(data, proj_geom, vol_geom, gpu_index, sampling)
+
+%--------------------------------------------------------------------------
+% [sino_id, sino] = astra_create_sino_cuda(data, proj_geom, vol_geom, gpu_index)
+%
+% Create a GPU based forward projection.
+%
+% data: input volume, can be either MATLAB-data or an astra-identifier.
+% proj_geom: MATLAB struct containing the projection geometry.
+% vol_geom: MATLAB struct containing the volume geometry.
+% gpu_index: the index of the GPU to use (optional).
+% sino_id: identifier of the sinogram data object as it is now stored in
+% the astra-library.
+% sino: MATLAB data version of the sinogram.
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+
+% store volume
+if (numel(data) > 1)
+ volume_id = astra_mex_data2d('create','-vol', vol_geom, data);
+else
+ volume_id = data;
+end
+
+% store sino
+sino_id = astra_mex_data2d('create','-sino', proj_geom, 0);
+
+% create sinogram
+cfg = astra_struct('FP_CUDA');
+cfg.ProjectionDataId = sino_id;
+cfg.VolumeDataId = volume_id;
+cfg.option.DetectorSuperSampling = sampling;
+if nargin > 3
+ cfg.option.GPUindex = gpu_index;
+end
+alg_id = astra_mex_algorithm('create', cfg);
+astra_mex_algorithm('iterate', alg_id);
+astra_mex_algorithm('delete', alg_id);
+
+if (numel(data) > 1)
+ astra_mex_data2d('delete', volume_id);
+end
+
+if nargout >= 2
+ sino = astra_mex_data2d('get',sino_id);
+end
+
+
+
diff --git a/matlab/tools/astra_create_vol_geom.m b/matlab/tools/astra_create_vol_geom.m
new file mode 100644
index 0000000..61db8fb
--- /dev/null
+++ b/matlab/tools/astra_create_vol_geom.m
@@ -0,0 +1,96 @@
+function vol_geom = astra_create_vol_geom(varargin)
+
+%--------------------------------------------------------------------------
+% vol_geom = astra_create_vol_geom([row_count col_count]);
+% vol_geom = astra_create_vol_geom(row_count, col_count);
+% vol_geom = astra_create_vol_geom(row_count, col_count, min_x, max_x, min_y, max_y);
+%
+% Create a 2D volume geometry. See the API for more information.
+% row_count: number of rows.
+% col_count: number of columns.
+% min_x: minimum value on the x-axis.
+% max_x: maximum value on the x-axis.
+% min_y: minimum value on the y-axis.
+% max_y: maximum value on the y-axis.
+% vol_geom: MATLAB struct containing all information of the geometry.
+%--------------------------------------------------------------------------
+% vol_geom = astra_create_vol_geom(row_count, col_count, slice_count);
+%
+% Create a 3D volume geometry. See the API for more information.
+% row_count: number of rows.
+% col_count: number of columns.
+% slice_count: number of slices.
+% vol_geom: MATLAB struct containing all information of the geometry.
+%--------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+% astra_create_vol_geom([row_and_col_count ])
+if numel(varargin) == 1 && numel(varargin{1}) == 1
+ vol_geom = struct();
+ vol_geom.GridRowCount = varargin{1}(1);
+ vol_geom.GridColCount = varargin{1}(1);
+ vol_geom.option.WindowMinX = -varargin{1}(1) / 2;
+ vol_geom.option.WindowMaxX = varargin{1}(1) / 2;
+ vol_geom.option.WindowMinY = -varargin{1}(1) / 2;
+ vol_geom.option.WindowMaxY = varargin{1}(1) / 2;
+
+
+% astra_create_vol_geom([row_count col_count])
+elseif numel(varargin) == 1 && numel(varargin{1}) == 2
+ vol_geom = struct();
+ vol_geom.GridRowCount = varargin{1}(1);
+ vol_geom.GridColCount = varargin{1}(2);
+ vol_geom.option.WindowMinX = -varargin{1}(2) / 2;
+ vol_geom.option.WindowMaxX = varargin{1}(2) / 2;
+ vol_geom.option.WindowMinY = -varargin{1}(1) / 2;
+ vol_geom.option.WindowMaxY = varargin{1}(1) / 2;
+
+% astra_create_vol_geom([row_count col_count slice_count])
+elseif numel(varargin) == 1 && numel(varargin{1}) == 3
+ vol_geom = struct();
+ vol_geom.GridRowCount = varargin{1}(1);
+ vol_geom.GridColCount = varargin{1}(2);
+ vol_geom.GridSliceCount = varargin{1}(3);
+ vol_geom.option.WindowMinX = -varargin{1}(2) / 2;
+ vol_geom.option.WindowMaxX = varargin{1}(2) / 2;
+ vol_geom.option.WindowMinY = -varargin{1}(1) / 2;
+ vol_geom.option.WindowMaxY = varargin{1}(1) / 2;
+ vol_geom.option.WindowMinZ = -varargin{1}(3) / 2;
+ vol_geom.option.WindowMaxZ = varargin{1}(3) / 2;
+
+% astra_create_vol_geom(row_count, col_count)
+elseif numel(varargin) == 2
+ vol_geom = struct();
+ vol_geom.GridRowCount = varargin{1};
+ vol_geom.GridColCount = varargin{2};
+ vol_geom.option.WindowMinX = -varargin{2} / 2;
+ vol_geom.option.WindowMaxX = varargin{2} / 2;
+ vol_geom.option.WindowMinY = -varargin{1} / 2;
+ vol_geom.option.WindowMaxY = varargin{1} / 2;
+
+% astra_create_vol_geom(row_count, col_count, min_x, max_x, min_y, max_y)
+elseif numel(varargin) == 6
+ vol_geom = struct();
+ vol_geom.GridRowCount = varargin{1};
+ vol_geom.GridColCount = varargin{2};
+ vol_geom.option.WindowMinX = varargin{3};
+ vol_geom.option.WindowMaxX = varargin{4};
+ vol_geom.option.WindowMinY = varargin{5};
+ vol_geom.option.WindowMaxY = varargin{6};
+
+% astra_create_vol_geom(row_count, col_count, slice_count)
+elseif numel(varargin) == 3
+ vol_geom = struct();
+ vol_geom.GridRowCount = varargin{1};
+ vol_geom.GridColCount = varargin{2};
+ vol_geom.GridSliceCount = varargin{3};
+end
diff --git a/matlab/tools/astra_data_gui.fig b/matlab/tools/astra_data_gui.fig
new file mode 100644
index 0000000..d73e430
--- /dev/null
+++ b/matlab/tools/astra_data_gui.fig
Binary files differ
diff --git a/matlab/tools/astra_data_gui.m b/matlab/tools/astra_data_gui.m
new file mode 100644
index 0000000..337a5d4
--- /dev/null
+++ b/matlab/tools/astra_data_gui.m
@@ -0,0 +1,396 @@
+function varargout = astra_data_gui(varargin)
+% ASTRA_DATA_GUI M-file for ASTRA_DATA_GUI.fig
+% ASTRA_DATA_GUI, by itself, creates a new ASTRA_DATA_GUI or raises the existing
+% singleton*.
+%
+% H = ASTRA_DATA_GUI returns the handle to a new ASTRA_DATA_GUI or the handle to
+% the existing singleton*.
+%
+% ASTRA_DATA_GUI('CALLBACK',hObject,eventData,handles,...) calls the local
+% function named CALLBACK in ASTRA_DATA_GUI.M with the given input arguments.
+%
+% ASTRA_DATA_GUI('Property','Value',...) creates a new ASTRA_DATA_GUI or raises the
+% existing singleton*. Starting from the left, property value pairs are
+% applied to the GUI before ASTRA_DATA_GUI_OpeningFcn gets called. An
+% unrecognized property name or invalid value makes property application
+% stop. All inputs are passed to ASTRA_DATA_GUI_OpeningFcn via varargin.
+%
+% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
+% instance to run (singleton)".
+%
+% See also: GUIDE, GUIDATA, GUIHANDLES
+
+% Edit the above text to modify the response to help ASTRA_DATA_GUI
+
+% Last Modified by GUIDE v2.5 05-Mar-2012 14:34:03
+
+% Begin initialization code - DO NOT EDIT
+gui_Singleton = 1;
+gui_State = struct('gui_Name', mfilename, ...
+ 'gui_Singleton', gui_Singleton, ...
+ 'gui_OpeningFcn', @astra_data_gui_OpeningFcn, ...
+ 'gui_OutputFcn', @astra_data_gui_OutputFcn, ...
+ 'gui_LayoutFcn', [] , ...
+ 'gui_Callback', []);
+if nargin && ischar(varargin{1})
+ gui_State.gui_Callback = str2func(varargin{1});
+end
+
+if nargout
+ [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
+else
+ gui_mainfcn(gui_State, varargin{:});
+end
+% End initialization code - DO NOT EDIT
+
+
+% --- Executes just before astra_data_gui is made visible.
+function astra_data_gui_OpeningFcn(hObject, eventdata, handles, varargin)
+% This function has no output args, see OutputFcn.
+% hObject handle to figure
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+% varargin command line arguments to astra_data_gui (see VARARGIN)
+
+% Choose default command line output for astra_data_gui
+handles.output = hObject;
+handles.data = [];
+
+% Update handles structure
+guidata(hObject, handles);
+
+% UIWAIT makes astra_data_gui wait for user response (see UIRESUME)
+% uiwait(handles.figure1);
+
+
+% --- Outputs from this function are returned to the command line.
+function varargout = astra_data_gui_OutputFcn(hObject, eventdata, handles)
+% varargout cell array for returning output args (see VARARGOUT);
+% hObject handle to figure
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Get default command line output from handles structure
+varargout{1} = handles.output;
+
+
+% Use this function to display a figure using the gui from any m-file
+% example:
+% Handle = astra_data_gui();
+% astra_data_gui('loadVolume',guihandles(Handle),'rand(30,30,30)',15);
+function loadVolume(handles,name,figure_number)
+set(handles.txt_var, 'String', name);
+set(handles.figure_number, 'String', num2str(figure_number));
+btn_load_Callback(handles.txt_var, [], handles);
+
+
+
+
+
+function txt_var_Callback(hObject, eventdata, handles) %#ok<*DEFNU>
+% hObject handle to txt_var (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hints: get(hObject,'String') returns contents of txt_var as text
+% str2double(get(hObject,'String')) returns contents of txt_var as a double
+
+
+% --- Executes during object creation, after setting all properties.
+function txt_var_CreateFcn(hObject, eventdata, handles)
+% hObject handle to txt_var (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: edit controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+
+% --- Executes on button press in btn_load.
+function btn_load_Callback(hObject, eventdata, handles)
+% hObject handle to btn_load (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+s = get(handles.txt_var, 'String');
+data = evalin('base', s);
+handles.data = data;
+guidata(hObject, handles);
+
+% Set Default Stuff
+set(handles.sld_slice, 'Min',1);
+set(handles.sld_slice, 'Max', size(data,3));
+set(handles.sld_slice, 'SliderStep', [1/(size(data,3)-2) 1/(size(data,3)-2)]);
+set(handles.sld_slice, 'Value', size(data,3)/2);
+
+sliderValue = floor(get(handles.sld_slice, 'Value'));
+set(handles.txt_slice, 'String', num2str(sliderValue));
+set(handles.txt_min, 'String', num2str(1));
+set(handles.txt_max, 'String', num2str(size(data,3)));
+
+set(handles.sld_magnification, 'Min',1);
+set(handles.sld_magnification, 'Max', 400);
+set(handles.sld_magnification, 'SliderStep', [1/(400-2) 1/(400-2)]);
+set(handles.sld_magnification, 'Value', 100);
+
+sliderValue3 = floor(get(handles.sld_magnification, 'Value'));
+set(handles.txt_mag, 'String', num2str(sliderValue3));
+
+
+figure_number = floor(str2double(get(handles.figure_number, 'String')));
+if(isnan(figure_number) || figure_number < 1)
+ set(handles.figure_number, 'String', num2str(10));
+end
+
+showimage(handles);
+
+% --- SHOW IMAGE
+function showimage(handles)
+ sliderValue = floor(get(handles.sld_slice, 'Value'));
+ magnification = floor(get(handles.sld_magnification, 'Value'));
+ figure_number = floor(str2double(get(handles.figure_number, 'String')));
+ image_matrix = handles.data;
+ if get(handles.btn_x, 'Value') == 1
+ figure(figure_number), imshow(sliceExtractor((image_matrix(:,:,:)), 'y', sliderValue),[],'InitialMagnification', magnification);
+ ylabel('y')
+ xlabel('z')
+ set(gcf,'Name','ASTRA DATA GUI')
+ elseif get(handles.btn_y, 'Value') == 1
+ figure(figure_number), imshow(sliceExtractor((image_matrix(:,:,:)), 'x', sliderValue),[],'InitialMagnification', magnification);
+ ylabel('x')
+ xlabel('z')
+ set(gcf,'Name','ASTRA DATA GUI')
+ else
+ figure(figure_number), imshow(sliceExtractor((image_matrix(:,:,:)), 'z', sliderValue),[],'InitialMagnification', magnification);
+ ylabel('x')
+ xlabel('y')
+ set(gcf,'Name','ASTRA DATA GUI')
+ end
+
+
+% --- Executes on slider movement.
+function sld_slice_Callback(hObject, eventdata, handles)
+% hObject handle to sld_slice (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+sliderValue = floor(get(handles.sld_slice, 'Value'));
+set(handles.txt_slice, 'String', num2str(sliderValue));
+showimage(handles);
+
+% --- Executes during object creation, after setting all properties.
+function sld_slice_CreateFcn(hObject, eventdata, handles)
+% hObject handle to sld_slice (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: slider controls usually have a light gray background.
+if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor',[.9 .9 .9]);
+end
+
+
+% --- Executes on button press in pushbutton2.
+function pushbutton2_Callback(hObject, eventdata, handles)
+% hObject handle to pushbutton2 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+
+% --- Executes on button press in pushbutton3.
+function pushbutton3_Callback(hObject, eventdata, handles)
+% hObject handle to pushbutton3 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+
+% --- Executes on button press in pushbutton4.
+function pushbutton4_Callback(hObject, eventdata, handles)
+% hObject handle to pushbutton4 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+
+function txt_slice_Callback(hObject, eventdata, handles)
+% hObject handle to txt_slice (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+slice = str2double(get(handles.txt_slice, 'String'));
+max = str2num(get(handles.txt_max,'String'));
+min = str2num(get(handles.txt_min,'String'));
+if(slice > max)
+ set(handles.txt_slice, 'String', num2str(max));
+ set(handles.sld_slice, 'Value', max);
+elseif(slice < min)
+ set(handles.txt_slice, 'String', num2str(min));
+ set(handles.sld_slice, 'Value', min);
+else
+ set(handles.sld_slice, 'Value', slice);
+end
+showimage(handles);
+
+% --- Executes during object creation, after setting all properties.
+function txt_slice_CreateFcn(hObject, eventdata, handles)
+% hObject handle to txt_slice (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: edit controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+% --- Executes on slider movement.
+function sld_magnification_Callback(hObject, eventdata, handles)
+% hObject handle to sld_slice2 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hints: get(hObject,'Value') returns position of slider
+% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
+sliderValue3 = floor(get(handles.sld_magnification, 'Value'));
+set(handles.txt_mag, 'String', num2str(sliderValue3));
+
+if(~isempty(handles.data))
+ showimage(handles);
+end
+
+
+
+% --- Executes during object creation, after setting all properties.
+function sld_magnification_CreateFcn(hObject, eventdata, handles)
+% hObject handle to sld_slice2 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+% Hint: slider controls usually have a light gray background.
+if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor',[.9 .9 .9]);
+end
+
+
+function txt_mag_Callback(hObject, eventdata, handles)
+% hObject handle to txt_slice2 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+magnification = str2double(get(handles.txt_mag, 'String'));
+if(magnification > 400)
+ set(handles.txt_mag, 'String', num2str(400));
+ set(handles.sld_magnification, 'Value', 400);
+elseif(magnification < 1)
+ set(handles.txt_mag, 'String', num2str(1));
+ set(handles.sld_magnification, 'Value', 1);
+else
+ set(handles.sld_magnification, 'Value', magnification);
+end
+
+if(~isempty(handles.data))
+ showimage(handles);
+end
+
+% --- Executes during object creation, after setting all properties.
+function txt_mag_CreateFcn(hObject, eventdata, handles)
+% hObject handle to txt_slice2 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+
+% Hint: edit controls usually have a white background on Windows.
+% See ISPC and COMPUTER.
+if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor','white');
+end
+
+% --- Executes on slider movement.
+function figure_number_Callback(hObject, eventdata, handles)
+% hObject handle to sld_slice2 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles structure with handles and user data (see GUIDATA)
+
+% Hints: get(hObject,'Value') returns position of slider
+% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
+number = floor(str2double(get(handles.figure_number, 'String')));
+if(number < 1)
+ set(handles.figure_number, 'String', num2str(1));
+else
+ set(handles.figure_number, 'String', num2str(number));
+end
+
+if(~isempty(handles.data))
+ showimage(handles);
+end
+
+
+% --- Executes during object creation, after setting all properties.
+function figure_number_CreateFcn(hObject, eventdata, handles)
+% hObject handle to sld_slice2 (see GCBO)
+% eventdata reserved - to be defined in a future version of MATLAB
+% handles empty - handles not created until after all CreateFcns called
+% Hint: slider controls usually have a light gray background.
+if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
+ set(hObject,'BackgroundColor',[.9 .9 .9]);
+end
+
+
+
+% --- Executes when selected object is changed in btn_dir.
+function btn_dir_SelectionChangeFcn(hObject, eventdata, handles)
+% hObject handle to the selected object in btn_dir
+% eventdata structure with the following fields (see UIBUTTONGROUP)
+% EventName: string 'SelectionChanged' (read only)
+% OldValue: handle of the previously selected object or empty if none was selected
+% NewValue: handle of the currently selected object
+% handles structure with handles and user data (see GUIDATA)
+
+data = handles.data;
+
+if(hObject == handles.btn_x)
+ set(handles.btn_x, 'Value', 1);
+ set(handles.btn_y, 'Value', 0);
+ set(handles.btn_z, 'Value', 0);
+elseif(hObject == handles.btn_y)
+ set(handles.btn_x, 'Value', 0);
+ set(handles.btn_y, 'Value', 1);
+ set(handles.btn_z, 'Value', 0);
+elseif(hObject == handles.btn_z)
+ set(handles.btn_x, 'Value', 0);
+ set(handles.btn_y, 'Value', 0);
+ set(handles.btn_z, 'Value', 1);
+end
+
+if get(handles.btn_x, 'Value') == 1
+ set(handles.sld_slice, 'Min',1);
+ set(handles.sld_slice, 'Max', size(data,1));
+ set(handles.sld_slice, 'SliderStep', [1/(size(data,1)-2) 1/(size(data,1)-2)]);
+ set(handles.sld_slice, 'Value', size(data,1)/2);
+
+ sliderValue = get(handles.sld_slice, 'Value');
+ set(handles.txt_slice, 'String', num2str(sliderValue));
+ set(handles.txt_min, 'String', num2str(1));
+ set(handles.txt_max, 'String', num2str(size(data,1)));
+
+elseif get(handles.btn_y, 'Value') == 1
+ set(handles.sld_slice, 'Min',1);
+ set(handles.sld_slice, 'Max', size(data,2));
+ set(handles.sld_slice, 'SliderStep', [1/(size(data,2)-2) 1/(size(data,2)-2)]);
+ set(handles.sld_slice, 'Value', size(data,2)/2);
+
+ sliderValue = get(handles.sld_slice, 'Value');
+ set(handles.txt_slice, 'String', num2str(sliderValue));
+ set(handles.txt_min, 'String', num2str(1));
+ set(handles.txt_max, 'String', num2str(size(data,2)));
+else
+ set(handles.sld_slice, 'Min',1);
+ set(handles.sld_slice, 'Max', size(data,3));
+ set(handles.sld_slice, 'SliderStep', [1/(size(data,3)-2) 1/(size(data,3)-2)]);
+ set(handles.sld_slice, 'Value', size(data,3)/2);
+
+ sliderValue = get(handles.sld_slice, 'Value');
+ set(handles.txt_slice, 'String', num2str(sliderValue));
+ set(handles.txt_min, 'String', num2str(1));
+ set(handles.txt_max, 'String', num2str(size(data,3)));
+end
+
+showimage(handles);
diff --git a/matlab/tools/astra_data_op.m b/matlab/tools/astra_data_op.m
new file mode 100644
index 0000000..b6ef0e2
--- /dev/null
+++ b/matlab/tools/astra_data_op.m
@@ -0,0 +1,11 @@
+function astra_data_op(op, data, scalar, gpu_core)
+
+cfg = astra_struct('DataOperation_CUDA');
+cfg.Operation = op;
+cfg.Scalar = scalar;
+cfg.DataId = data;
+cfg.option.GPUindex = gpu_core;
+
+alg_id = astra_mex_algorithm('create',cfg);
+astra_mex_algorithm('run',alg_id);
+astra_mex_algorithm('delete',alg_id); \ No newline at end of file
diff --git a/matlab/tools/astra_data_op_mask.m b/matlab/tools/astra_data_op_mask.m
new file mode 100644
index 0000000..d46c925
--- /dev/null
+++ b/matlab/tools/astra_data_op_mask.m
@@ -0,0 +1,12 @@
+function astra_data_op_mask(op, data, scalar, mask, gpu_core)
+
+cfg = astra_struct('DataOperation_CUDA');
+cfg.Operation = op;
+cfg.Scalar = scalar;
+cfg.DataId = data;
+cfg.option.GPUindex = gpu_core;
+cfg.option.MaskId = mask;
+
+alg_id = astra_mex_algorithm('create',cfg);
+astra_mex_algorithm('run',alg_id);
+astra_mex_algorithm('delete',alg_id); \ No newline at end of file
diff --git a/matlab/tools/astra_downsample_sinogram.m b/matlab/tools/astra_downsample_sinogram.m
new file mode 100644
index 0000000..30c1cdd
--- /dev/null
+++ b/matlab/tools/astra_downsample_sinogram.m
@@ -0,0 +1,36 @@
+function [sinogram_new, proj_geom_new] = astra_downsample_sinogram(sinogram, proj_geom, factor)
+
+%------------------------------------------------------------------------
+% [sinogram_new, proj_geom_new] = astra_downsample_sinogram(sinogram, proj_geom, factor)
+%
+% Downsample the sinogram with some factor and adjust projection geometry
+% accordingly
+%
+% sinogram: MATLAB data version of the sinogram.
+% proj_geom: MATLAB struct containing the projection geometry.
+% factor: the factor by which the number of detectors is divided.
+% sinogram_new: MATLAB data version of the resampled sinogram.
+% proj_geom_new: MATLAB struct containing the new projection geometry.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+if mod(size(sinogram,2),factor) ~= 0
+ disp('size of the sinogram must be a divisor of the factor');
+end
+
+sinogram_new = zeros(size(sinogram,1),size(sinogram,2)/factor);
+for i = 1:size(sinogram,2)/factor
+ sinogram_new(:,i) = sum(sinogram(:,(factor*(i-1)+1):factor*i),2);
+end
+
+proj_geom_new = proj_geom;
+proj_geom_new.DetectorCount = proj_geom_new.DetectorCount / factor;
diff --git a/matlab/tools/astra_geom_2vec.m b/matlab/tools/astra_geom_2vec.m
new file mode 100644
index 0000000..0abd07c
--- /dev/null
+++ b/matlab/tools/astra_geom_2vec.m
@@ -0,0 +1,84 @@
+function proj_geom_out = astra_geom_2vec(proj_geom)
+
+ % FANFLAT
+ if strcmp(proj_geom.type,'fanflat')
+
+ vectors = zeros(numel(proj_geom.ProjectionAngles), 6);
+ for i = 1:numel(proj_geom.ProjectionAngles)
+
+ % source
+ vectors(i,1) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginSource;
+ vectors(i,2) = -cos(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginSource;
+
+ % center of detector
+ vectors(i,3) = -sin(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginDetector;
+ vectors(i,4) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginDetector;
+
+ % vector from detector pixel 0 to 1
+ vectors(i,5) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorWidth;
+ vectors(i,6) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorWidth;
+ end
+
+ proj_geom_out = astra_create_proj_geom('fanflat_vec', proj_geom.DetectorCount, vectors);
+
+ % CONE
+ elseif strcmp(proj_geom.type,'cone')
+
+ vectors = zeros(numel(proj_geom.ProjectionAngles), 12);
+ for i = 1:numel(proj_geom.ProjectionAngles)
+
+ % source
+ vectors(i,1) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginSource;
+ vectors(i,2) = -cos(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginSource;
+ vectors(i,3) = 0;
+
+ % center of detector
+ vectors(i,4) = -sin(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginDetector;
+ vectors(i,5) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginDetector;
+ vectors(i,6) = 0;
+
+ % vector from detector pixel (0,0) to (0,1)
+ vectors(i,7) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorSpacingX;
+ vectors(i,8) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorSpacingX;
+ vectors(i,9) = 0;
+
+ % vector from detector pixel (0,0) to (1,0)
+ vectors(i,10) = 0;
+ vectors(i,11) = 0;
+ vectors(i,12) = proj_geom.DetectorSpacingY;
+ end
+
+ proj_geom_out = astra_create_proj_geom('cone_vec', proj_geom.DetectorRowCount, proj_geom.DetectorColCount, vectors);
+
+ % PARALLEL
+ elseif strcmp(proj_geom.type,'parallel3d')
+
+ vectors = zeros(numel(proj_geom.ProjectionAngles), 12);
+ for i = 1:numel(proj_geom.ProjectionAngles)
+
+ % ray direction
+ vectors(i,1) = sin(proj_geom.ProjectionAngles(i));
+ vectors(i,2) = -cos(proj_geom.ProjectionAngles(i));
+ vectors(i,3) = 0;
+
+ % center of detector
+ vectors(i,4) = 0;
+ vectors(i,5) = 0;
+ vectors(i,6) = 0;
+
+ % vector from detector pixel (0,0) to (0,1)
+ vectors(i,7) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorSpacingX;
+ vectors(i,8) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorSpacingX;
+ vectors(i,9) = 0;
+
+ % vector from detector pixel (0,0) to (1,0)
+ vectors(i,10) = 0;
+ vectors(i,11) = 0;
+ vectors(i,12) = proj_geom.DetectorSpacingY;
+ end
+
+ proj_geom_out = astra_create_proj_geom('parallel3d_vec', proj_geom.DetectorRowCount, proj_geom.DetectorColCount, vectors);
+
+ else
+ error(['No suitable vector geometry found for type: ' proj_geom.type])
+ end
diff --git a/matlab/tools/astra_geom_postalignment.m b/matlab/tools/astra_geom_postalignment.m
new file mode 100644
index 0000000..4115af2
--- /dev/null
+++ b/matlab/tools/astra_geom_postalignment.m
@@ -0,0 +1,11 @@
+function proj_geom = astra_geom_postalignment(proj_geom, factor)
+
+ if strcmp(proj_geom.type,'fanflat_vec')
+ proj_geom.Vectors(:,3:4) = proj_geom.Vectors(:,3:4) + factor * proj_geom.Vectors(:,5:6);
+
+ elseif strcmp(proj_geom.type,'cone_vec') || strcmp(proj_geom.type,'parallel3d_vec')
+ proj_geom.Vectors(:,4:6) = proj_geom.Vectors(:,4:6) + factor * proj_geom.Vectors(:,7:9);
+
+ else
+ error('Projection geometry not suited for postalignment correction.')
+ end
diff --git a/matlab/tools/astra_geom_size.m b/matlab/tools/astra_geom_size.m
new file mode 100644
index 0000000..c4956f5
--- /dev/null
+++ b/matlab/tools/astra_geom_size.m
@@ -0,0 +1,28 @@
+function s = astra_geom_size(geom, dim)
+
+ if isfield(geom, 'GridSliceCount')
+ % 3D Volume geometry?
+ s = [ geom.GridColCount, geom.GridRowCount, geom.GridSliceCount ];
+ elseif isfield(geom, 'GridColCount')
+ % 2D Volume geometry?
+ s = [ geom.GridRowCount, geom.GridColCount ];
+ elseif strcmp(geom.type,'parallel') || strcmp(geom.type,'fanflat')
+ s = [numel(geom.ProjectionAngles), geom.DetectorCount];
+
+ elseif strcmp(geom.type,'parallel3d') || strcmp(geom.type,'cone')
+ s = [geom.DetectorRowCount, numel(geom.ProjectionAngles), geom.DetectorColCount];
+
+ elseif strcmp(geom.type,'fanflat_vec')
+ s = [size(geom.Vectors,1), geom.DetectorCount];
+
+ elseif strcmp(geom.type,'parallel3d_vec') || strcmp(geom.type,'cone_vec')
+ s = [geom.DetectorColCount, size(geom.Vectors,1), geom.DetectorRowCount];
+
+ end
+
+ if nargin == 2
+ s = s(dim);
+ end
+
+end
+
diff --git a/matlab/tools/astra_geom_superresolution.m b/matlab/tools/astra_geom_superresolution.m
new file mode 100644
index 0000000..b2b0ebf
--- /dev/null
+++ b/matlab/tools/astra_geom_superresolution.m
@@ -0,0 +1,14 @@
+function proj_geom = astra_geom_superresolution(proj_geom, factor)
+
+ if strcmp(proj_geom.type,'parallel')
+ proj_geom.DetectorWidth = proj_geom.DetectorWidth/factor;
+ proj_geom.DetectorCount = proj_geom.DetectorCount * factor;
+ elseif strcmp(proj_geom.type,'fanflat')
+ proj_geom.DetectorWidth = proj_geom.DetectorWidth/factor;
+ proj_geom.DetectorCount = proj_geom.DetectorCount * factor;
+ elseif strcmp(proj_geom.type,'fanflat_vec')
+ proj_geom.Vectors(:,5:6) = proj_geom.Vectors(:,5:6) / factor; % DetectorSize
+ proj_geom.DetectorCount = proj_geom.DetectorCount * factor;
+ else
+ error('Projection geometry not suited for super-resolution (or not implemented).')
+ end
diff --git a/matlab/tools/astra_imshow.m b/matlab/tools/astra_imshow.m
new file mode 100644
index 0000000..6069674
--- /dev/null
+++ b/matlab/tools/astra_imshow.m
@@ -0,0 +1,10 @@
+function V = astra_imshow(data, range)
+
+if numel(data) == 1
+ data = astra_mex_data2d('get', data);
+end
+imshow(data,range);
+
+if nargout >= 1
+ V = data;
+end \ No newline at end of file
diff --git a/matlab/tools/astra_mex.m b/matlab/tools/astra_mex.m
new file mode 100644
index 0000000..e04cfea
--- /dev/null
+++ b/matlab/tools/astra_mex.m
@@ -0,0 +1,24 @@
+function [varargout] = astra_mex(varargin)
+%------------------------------------------------------------------------
+% Reference page in Help browser
+% <a href="matlab:docsearch('astra_mex' )">astra_mex</a>.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+if nargout == 0
+ astra_mex_c(varargin{:});
+ if exist('ans','var')
+ varargout{1} = ans;
+ end
+else
+ varargout = cell(1,nargout);
+ [varargout{:}] = astra_mex_c(varargin{:});
+end
diff --git a/matlab/tools/astra_mex_algorithm.m b/matlab/tools/astra_mex_algorithm.m
new file mode 100644
index 0000000..138a43c
--- /dev/null
+++ b/matlab/tools/astra_mex_algorithm.m
@@ -0,0 +1,24 @@
+function [varargout] = astra_mex_algorithm(varargin)
+%------------------------------------------------------------------------
+% Reference page in Help browser
+% <a href="matlab:docsearch('astra_mex_algorithm' )">astra_mex_algorithm</a>.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+if nargout == 0
+ astra_mex_algorithm_c(varargin{:});
+ if exist('ans','var')
+ varargout{1} = ans;
+ end
+else
+ varargout = cell(1,nargout);
+ [varargout{:}] = astra_mex_algorithm_c(varargin{:});
+end
diff --git a/matlab/tools/astra_mex_data2d.m b/matlab/tools/astra_mex_data2d.m
new file mode 100644
index 0000000..eacbcb9
--- /dev/null
+++ b/matlab/tools/astra_mex_data2d.m
@@ -0,0 +1,24 @@
+function [varargout] = astra_mex_data2d(varargin)
+%------------------------------------------------------------------------
+% Reference page in Help browser
+% <a href="matlab:docsearch('astra_mex_data2d' )">astra_mex_data2d</a>.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+if nargout == 0
+ astra_mex_data2d_c(varargin{:});
+ if exist('ans','var')
+ varargout{1} = ans;
+ end
+else
+ varargout = cell(1,nargout);
+ [varargout{:}] = astra_mex_data2d_c(varargin{:});
+end
diff --git a/matlab/tools/astra_mex_data3d.m b/matlab/tools/astra_mex_data3d.m
new file mode 100644
index 0000000..3bbbd68
--- /dev/null
+++ b/matlab/tools/astra_mex_data3d.m
@@ -0,0 +1,24 @@
+function [varargout] = astra_mex_data3d(varargin)
+%------------------------------------------------------------------------
+% Reference page in Help browser
+% <a href="matlab:docsearch('astra_mex_data3d' )">astra_mex_data3d</a>.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+if nargout == 0
+ astra_mex_data3d_c(varargin{:});
+ if exist('ans','var')
+ varargout{1} = ans;
+ end
+else
+ varargout = cell(1,nargout);
+ [varargout{:}] = astra_mex_data3d_c(varargin{:});
+end
diff --git a/matlab/tools/astra_mex_matrix.m b/matlab/tools/astra_mex_matrix.m
new file mode 100644
index 0000000..182ab1e
--- /dev/null
+++ b/matlab/tools/astra_mex_matrix.m
@@ -0,0 +1,24 @@
+function [varargout] = astra_mex_matrix(varargin)
+%------------------------------------------------------------------------
+% Reference page in Help browser
+% <a href="matlab:docsearch('astra_mex_matrix' )">astra_mex_matrix</a>.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+if nargout == 0
+ astra_mex_matrix_c(varargin{:});
+ if exist('ans','var')
+ varargout{1} = ans;
+ end
+else
+ varargout = cell(1,nargout);
+ [varargout{:}] = astra_mex_matrix_c(varargin{:});
+end
diff --git a/matlab/tools/astra_mex_projector.m b/matlab/tools/astra_mex_projector.m
new file mode 100644
index 0000000..487da06
--- /dev/null
+++ b/matlab/tools/astra_mex_projector.m
@@ -0,0 +1,24 @@
+function [varargout] = astra_mex_projector(varargin)
+%------------------------------------------------------------------------
+% Reference page in Help browser
+% <a href="matlab:docsearch('astra_mex_projector' )">astra_mex_projector</a>.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+if nargout == 0
+ astra_mex_projector_c(varargin{:});
+ if exist('ans','var')
+ varargout{1} = ans;
+ end
+else
+ varargout = cell(1,nargout);
+ [varargout{:}] = astra_mex_projector_c(varargin{:});
+end
diff --git a/matlab/tools/astra_mex_projector3d.m b/matlab/tools/astra_mex_projector3d.m
new file mode 100644
index 0000000..3d21ce9
--- /dev/null
+++ b/matlab/tools/astra_mex_projector3d.m
@@ -0,0 +1,24 @@
+function [varargout] = astra_mex_projector3d(varargin)
+%------------------------------------------------------------------------
+% Reference page in Help browser
+% <a href="matlab:docsearch('astra_mex_projector3d' )">astra_mex_projector3d</a>.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+if nargout == 0
+ astra_mex_projector3d_c(varargin{:});
+ if exist('ans','var')
+ varargout{1} = ans;
+ end
+else
+ varargout = cell(1,nargout);
+ [varargout{:}] = astra_mex_projector3d_c(varargin{:});
+end
diff --git a/matlab/tools/astra_projector_handle.m b/matlab/tools/astra_projector_handle.m
new file mode 100644
index 0000000..72d4c73
--- /dev/null
+++ b/matlab/tools/astra_projector_handle.m
@@ -0,0 +1,29 @@
+classdef astra_projector_handle < handle
+ %ASTRA_PROJECTOR_HANDLE Handle class around an astra_mex_projector id
+ % Automatically deletes the projector when deleted.
+
+ %------------------------------------------------------------------------
+ % This file is part of the
+ % All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+ %
+ % Copyright: iMinds-Vision Lab, University of Antwerp
+ % License: Open Source under GPLv3
+ % Contact: mailto:astra@ua.ac.be
+ % Website: http://astra.ua.ac.be
+ %------------------------------------------------------------------------
+
+ properties
+ id
+ end
+
+ methods
+ function obj = astra_projector_handle(proj_id)
+ obj.id = proj_id;
+ end
+ function delete(obj)
+ astra_mex_projector('delete', obj.id);
+ end
+ end
+
+end
+
diff --git a/matlab/tools/astra_set_directory.m b/matlab/tools/astra_set_directory.m
new file mode 100644
index 0000000..1d5a368
--- /dev/null
+++ b/matlab/tools/astra_set_directory.m
@@ -0,0 +1,27 @@
+function in = astra_set_directory(in)
+
+%------------------------------------------------------------------------
+% in = astra_set_directory(in)
+%
+% Creates the directories present in the input path if they do not exist
+% already
+%
+% in: input path.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+a = find(in == '/' | in == '\');
+for i = 1:numel(a)
+ if ~isdir(in(1:a(i)))
+ mkdir(in(1:a(i)));
+ end
+end
diff --git a/matlab/tools/astra_struct.m b/matlab/tools/astra_struct.m
new file mode 100644
index 0000000..f65b2ec
--- /dev/null
+++ b/matlab/tools/astra_struct.m
@@ -0,0 +1,37 @@
+function res = astra_struct(type)
+
+%------------------------------------------------------------------------
+% res = astra_struct(type)
+%
+% Create an ASTRA struct
+%
+% type: type of the struct to be generated.
+% res: the generated matlab struct.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+res = struct();
+res.options = struct();
+
+
+if nargin >= 1
+ % For backward compatibility, transparently accept SIRT_CUDA2
+ % for SIRT_CUDA, and FP_CUDA2 for FP_CUDA.
+ if strcmp(type, 'SIRT_CUDA2')
+ type = 'SIRT_CUDA';
+ warning('SIRT_CUDA2 has been deprecated. Use SIRT_CUDA instead.');
+ end
+ if strcmp(type, 'FP_CUDA2')
+ type = 'FP_CUDA';
+ warning('FP_CUDA2 has been deprecated. Use FP_CUDA instead.');
+ end
+ res.type = type;
+end
diff --git a/matlab/tools/compute_rnmp.m b/matlab/tools/compute_rnmp.m
new file mode 100644
index 0000000..6c00a01
--- /dev/null
+++ b/matlab/tools/compute_rnmp.m
@@ -0,0 +1,29 @@
+function [rnmp, nmp] = compute_rnmp(phantom, S)
+
+ phantom = double(phantom == max(phantom(:)));
+ S = double(S == max(S(:)));
+
+ %u1 = sort(unique(phantom));
+ %u2 = sort(unique(S));
+ %for i = 1:numel(u1)
+ % phantom_(phantom == u1(i)) = i;
+ % S_(S == u2(i)) = i;
+ %end
+ %phantom = phantom_;
+ %S = S_;
+
+ if numel(size(phantom)) == 2
+ S = imresize(S, size(phantom), 'nearest');
+ elseif numel(size(phantom)) == 3
+ S2 = zeros(size(phantom));
+ for slice = 1:size(phantom,3)
+ S2(:,:,slice) = imresize(S(:,:,slice), [size(phantom,1) size(phantom,2)], 'nearest');
+ end
+ S = S2;
+ end
+
+ nmp = sum(abs(phantom(:) ~= S(:)));
+ rnmp = nmp / sum(phantom(:));
+
+end
+
diff --git a/matlab/tools/createOrderART.m b/matlab/tools/createOrderART.m
new file mode 100644
index 0000000..a469d8a
--- /dev/null
+++ b/matlab/tools/createOrderART.m
@@ -0,0 +1,66 @@
+function rayOrder = createOrderART(proj_geom, mode)
+
+%------------------------------------------------------------------------
+% rayOrder = createOrderART(proj_geom, mode)
+%
+% Creates an array defining the order in which ART will iterate over the
+% projections and projection rays
+%
+% proj_geom: MATLAB struct containing the projection geometry.
+% mode: string defining the wanted ray order, can be either 'sequential',
+% 'randomray' or 'randomproj'.
+% rayOrder: array of two columns of length angle_count * det_count, with
+% the first column being the index of the projection and the second column
+% the index of the ray.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+angle_count = length(proj_geom.projection_angles);
+det_count = proj_geom.detector_count;
+
+% create order
+rayOrder = zeros(angle_count * det_count, 2);
+if strcmp(mode,'sequential') == 1
+ index = 1;
+ for i = 1:angle_count
+ for j = 1:det_count
+ rayOrder(index,1) = i;
+ rayOrder(index,2) = j;
+ index = index + 1;
+ end
+ end
+elseif strcmp(mode,'randomray') == 1
+ index = 1;
+ for i = 1:angle_count
+ for j = 1:det_count
+ rayOrder(index,1) = i;
+ rayOrder(index,2) = j;
+ index = index + 1;
+ end
+ end
+ r = randperm(angle_count * det_count);
+ rayOrder(:,1) = rayOrder(r,1);
+ rayOrder(:,2) = rayOrder(r,2);
+elseif strcmp(mode,'randomproj') == 1
+ index = 1;
+ r = randperm(angle_count);
+ for i = 1:angle_count
+ for j = 1:det_count
+ rayOrder(index,1) = r(i);
+ rayOrder(index,2) = j;
+ index = index + 1;
+ end
+ end
+else
+ disp('mode not known');
+end
+
diff --git a/matlab/tools/downsample_sinogram.m b/matlab/tools/downsample_sinogram.m
new file mode 100644
index 0000000..1fb4ec8
--- /dev/null
+++ b/matlab/tools/downsample_sinogram.m
@@ -0,0 +1,12 @@
+function sinogram_out = downsample_sinogram(sinogram, ds)
+
+ if ds == 1
+ sinogram_out = sinogram;
+ return;
+ end
+
+ sinogram_out = sinogram(:,1:ds:end,:);
+ for i = 2:ds
+ sinogram_out = sinogram_out + sinogram(:,i:ds:end,:);
+ end
+ sinogram_out = sinogram_out / (ds*ds); \ No newline at end of file
diff --git a/matlab/tools/imreadgs.m b/matlab/tools/imreadgs.m
new file mode 100644
index 0000000..9c27eb4
--- /dev/null
+++ b/matlab/tools/imreadgs.m
@@ -0,0 +1,26 @@
+function Im = imreadgs(filename)
+
+%------------------------------------------------------------------------
+% Im = imreadgs(filename)
+%
+% Reads an image and transforms it into a grayscale image consisting of
+% doubles.
+%
+% filename: name of the image file.
+% Im: a grayscale image in double.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+Im = double(imread(filename));
+if size(Im,3) > 1
+ Im = Im(:,:,1);
+end
diff --git a/matlab/tools/imresize3D.m b/matlab/tools/imresize3D.m
new file mode 100644
index 0000000..9032cc3
--- /dev/null
+++ b/matlab/tools/imresize3D.m
@@ -0,0 +1,26 @@
+function out = imresize3D(in, s_out, method)
+
+%------------------------------------------------------------------------
+% out = imresize3D(in, s_out, method)
+%
+% Resizes a 3-component image
+%
+% in: input image.
+% s_out: 2 element array with the wanted image size, [rows columns].
+% out: the resized 3-component image.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+out = zeros(s_out);
+for i = 1:size(in,3)
+ out(:,:,i) = imresize(in(:,:,i), s_out(1:2), method);
+end
diff --git a/matlab/tools/imscale.m b/matlab/tools/imscale.m
new file mode 100644
index 0000000..957f11f
--- /dev/null
+++ b/matlab/tools/imscale.m
@@ -0,0 +1,28 @@
+function out = imscale(in)
+
+%------------------------------------------------------------------------
+% out = imscale(in)
+%
+% Rescales the image values between zero and one.
+%
+% in: input image.
+% out: scaled output image.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+mi = min(in(:));
+ma = max(in(:));
+if (ma-mi) == 0
+ out = zeros(size(in));
+else
+ out = (in - mi) / (ma - mi);
+end
diff --git a/matlab/tools/imwritesc.m b/matlab/tools/imwritesc.m
new file mode 100644
index 0000000..2f81dc8
--- /dev/null
+++ b/matlab/tools/imwritesc.m
@@ -0,0 +1,22 @@
+function imwritesc(in, filename)
+
+%------------------------------------------------------------------------
+% imwritesc(in, filename)
+%
+% Rescale between zero and one and write image
+%
+% in: input image.
+% filename: name of output image file.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+imwrite(imscale(in),filename);
diff --git a/matlab/tools/kaiserBessel.m b/matlab/tools/kaiserBessel.m
new file mode 100644
index 0000000..aef7b9d
--- /dev/null
+++ b/matlab/tools/kaiserBessel.m
@@ -0,0 +1,31 @@
+function res = kaiserBessel(m,alpha,a,r)
+
+%------------------------------------------------------------------------
+% res = kaiserBessel(m,alpha,a,r)
+%
+% Calculates the Kaiser windowing function
+%
+% a: length of the sequence.
+% m: order.
+% alpha: determines shape of window.
+% r: input values for which to compute window value.
+% res: the window values.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+sq = sqrt(1 - (r./a).^2);
+
+res1 = 1 ./ besseli(m, alpha);
+res2 = sq .^ m;
+res3 = besseli(m, alpha .* sq);
+
+res = res1 .* res2 .* res3;
diff --git a/matlab/tools/linspace2.m b/matlab/tools/linspace2.m
new file mode 100644
index 0000000..2787fd9
--- /dev/null
+++ b/matlab/tools/linspace2.m
@@ -0,0 +1,25 @@
+function out = linspace2(a,b,c)
+
+%------------------------------------------------------------------------
+% out = linspace2(a,b,c)
+%
+% Generates linearly spaced vectors
+%
+% a: lower limit.
+% b: upper limit (exclusive).
+% c: number of elements.
+% out: linearly spaced vector.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+out = linspace(a,b,c+1);
+out = out(1:end-1);
diff --git a/matlab/tools/overlayImage.m b/matlab/tools/overlayImage.m
new file mode 100644
index 0000000..7c81e55
--- /dev/null
+++ b/matlab/tools/overlayImage.m
@@ -0,0 +1,24 @@
+function im = overlayImage(reconstruction, ground_truth)
+%------------------------------------------------------------------------
+% im = overlayImage(reconstruction, ground_truth)
+%
+% Produces an overlay image of two images, useful for image comparison.
+%
+% reconstruction: first input image matrix.
+% ground_truth: second input image matrix.
+% im: output 3-component image, third channel is 0.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+im(:,:,1) = reconstruction ./ max(reconstruction(:));
+im(:,:,2) = ground_truth ./ max(ground_truth(:));
+im(:,:,3) = zeros(size(reconstruction));
diff --git a/matlab/tools/rebin_fan2par.m b/matlab/tools/rebin_fan2par.m
new file mode 100644
index 0000000..da20932
--- /dev/null
+++ b/matlab/tools/rebin_fan2par.m
@@ -0,0 +1,82 @@
+function F = rebin_fan2par(RadonData, BetaDeg, D, thetaDeg)
+
+%------------------------------------------------------------------------
+% F = rebin_fan2par(RadonData, BetaDeg, D, thetaDeg)
+%
+% Deze functie zet fan beam data om naar parallelle data, door interpolatie
+% (fast resorting algorithm, zie Kak en Slaney)
+% Radondata zoals altijd: eerste coord gamma , de rijen
+% tweede coord beta, de kolommen, beide hoeken in
+% radialen
+% PixPProj: aantal pixels per projectie (voor skyscan data typisch 1000)
+% BetaDeg: vector met alle draaihoeken in graden
+% D: afstand bron - rotatiecentrum in pixels, dus afstand
+% bron-rotatiecentrum(um) gedeeld door image pixel size (um).
+% thetaDeg: vector met gewenste sinogramwaarden voor theta in graden
+% de range van thetaDeg moet steeds kleiner zijn dan die van betadeg
+% D,gamma,beta, theta zoals gebruikt in Kak & Slaney
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+NpixPProj = size(RadonData,1); % aantal pixels per projectie
+%if mod(size(Radondata,1),2)==0
+% NpixPProjNew=NpixPProj+1;
+%else
+ NpixPProjNew = NpixPProj;
+%end
+
+%% FAN-BEAM RAYS
+
+% flip sinogram, why?
+RadonData = flipdim(RadonData,2); % matlab gebruikt tegengestelde draairichting (denkik) als skyscan, of er is een of andere flipdim geweest die gecorrigeerd moet worden))
+
+% DetPixPos: distance of each detector to the ray through the origin (theta)
+DetPixPos = -(NpixPProj-1)/2:(NpixPProj-1)/2; % posities detectorpixels
+
+% GammaStralen: alpha's? (result in radians!!)
+GammaStralen = atan(DetPixPos/D); % alle met de detectorpixelposities overeenkomstige gammahoeken
+
+% put beta (theta) and gamma (alpha) for each ray in 2D matrices
+[beta gamma] = meshgrid(BetaDeg,GammaStralen);
+
+% t: minimal distance between each ray and the ray through the origin
+t = D*sin(gamma); % t-waarden overeenkomstig met de verschillende gamma's
+
+theta = gamma*180/pi + beta; % theta-waarden in graden overeenkomstig met verschillende gamma en beta waarden
+
+%% PARALLEL BEAM RAYS
+
+% DetPixPos: distance of each detector to the ray through the origin (theta)
+DetPixPos = -(NpixPProjNew-1)/2:(NpixPProjNew-1)/2; % posities detectorpixels
+
+% GammaStralen: alpha's? (result in radians!!)
+GammaStralenNew = atan(DetPixPos/D); % alle met de detectorpixelposities overeenkomstige gammahoeken
+
+% put beta (theta) and gamma (alpha) for each ray in 2D matrices
+[~, gamma] = meshgrid(BetaDeg,GammaStralenNew);
+
+% t: minimal distance between each ray and the ray through the origin
+tnew = D * sin(gamma); % t-waarden overeenkomstig met de verschillende gamma's
+
+% calculate new t
+step = (max(tnew)-min(tnew)) / (NpixPProjNew-1);
+t_para = min(tnew):step:max(tnew);
+
+[thetaNewCoord tNewCoord] = meshgrid(thetaDeg, t_para);
+
+%% Interpolate
+Interpolant = TriScatteredInterp(theta(:), t(:), RadonData(:),'nearest');
+F = Interpolant(thetaNewCoord,tNewCoord);
+
+
+
+
diff --git a/matlab/tools/sliceExtractor.m b/matlab/tools/sliceExtractor.m
new file mode 100644
index 0000000..dfc87ee
--- /dev/null
+++ b/matlab/tools/sliceExtractor.m
@@ -0,0 +1,34 @@
+function slice = sliceExtractor(data, dir, slicenr)
+
+%------------------------------------------------------------------------
+% slice = sliceExtractor(data, dir, slicenr)
+%
+% Outputs a specified slice from a three dimensional matrix/volume
+%
+% data: the 3D volume.
+% dir: the direction in which the volume is sliced.
+% slicenr: the index of the slice to retrieve.
+% slice: 2D image matrix containing the slice.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the
+% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox")
+%
+% Copyright: iMinds-Vision Lab, University of Antwerp
+% License: Open Source under GPLv3
+% Contact: mailto:astra@ua.ac.be
+% Website: http://astra.ua.ac.be
+%------------------------------------------------------------------------
+% $Id$
+
+slicenr = round(slicenr);
+
+if strcmp(dir,'z')
+ slice = squeeze(data(:,:,slicenr));
+end
+if strcmp(dir,'x')
+ slice = squeeze(data(:,slicenr,:));
+end
+if strcmp(dir,'y')
+ slice = squeeze(data(slicenr,:,:));
+end