Files
fold_slice/tomo/tests/test_tomo_simulated_data.m
T
2026-08-07 15:56:42 +09:00

218 lines
9.0 KiB
Matlab
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
%% TEMPLATE FOR AUTOMATIC TOMOGRAPHY CODE TESTS
% test uses synthetic data to run all templates under well controlled
% conditions, use setting if you want to add noise or other difficulties to
% be tested during alignment
cd(fullfile( fileparts(mfilename('fullpath')), '..'))
addpath('tests')
addpath('utils')
addpath('./')
addpath(find_base_package)
%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Edit this section %%%
%%%%%%%%%%%%%%%%%%%%%%%%%
tested_templates = 1:3; % IDs of the tested templates
templates_list ={ 'template_tomo_recons', ...
'template_tomo_recons_lamino', ...
'template_tomo_nonrigid', ...
'template_tomo_recons_deprecated'...
};
verbose_level = -1; % -1 = keep very quiet the reconstructions
% artificial data settings
Npix_vol = [200,200,200] ;
undersampling = 1; % level of undersampling compared to Crowther criterion
noise_level = 0; % relative noise level with respect to the maximal phase value in the projections
N_subtomos = 4;
add_residual_layer = false; % add a thin metal-like layer to test behaviour with residua
Nangles = ceil(pi/2*Npix_vol(1)) / undersampling;
Nangles = ceil(Nangles/N_subtomos)*N_subtomos; % make splitable for 4 subtomos
asize = ceil(Npix_vol(1:2) / 10); % size of the simulated probe
if ~exist('GPU_id', 'var'); GPU_id = [1]; end
if ~exist('base_path', 'var'); base_path = '../'; end
%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%
assert(all(GPU_id <= gpuDeviceCount), 'Select valid GPU id in GPU_id')
utils.verbose(verbose_level)
setenv('TMP',[base_path,'/tmp']) % TEMP for matlab scripts
%% MAKE A PHANTOM
utils.verbose(-1,'Creating phantom')
rng default
volData = randn(Npix_vol - asize(1), 'single');
volData = (0.5+0.5*(utils.imgaussfilt3_fft(volData, 3) > 0)) .* ...
(utils.imgaussfilt3_fft(volData, 10) > 0);
volData = utils.imgaussfilt3_conv(volData, 0.6); % prevent too sharp edges
if add_residual_layer
% add kind of metalic layer to test robustness of the codes
[X,Y,Z] = meshgrid(-Npix_vol(1)/2:Npix_vol(1)/2-1,-Npix_vol(2)/2:Npix_vol(2)/2-1,-Npix_vol(3)/2:Npix_vol(3)/2-1);
layer = abs(0.1*X + 0.5*Y+0.2*Z + 50*utils.imgaussfilt3_fft(randn(Npix_vol, 'single'),10) )<0.5;
volData = volData + 10*utils.crop_pad_3D(layer, size(volData));
end
volData = utils.apply_3D_apodization(volData, 0, Npix_vol(1)/5, 1);
volData = utils.crop_pad_3D(volData, Npix_vol);
for tested_template = templates_list(tested_templates)
utils.verbose(struct('prefix', 'init'))
%% test stage 0: load basic configuration parameters
utils.verbose(-1,'Loading template "%s"', tested_template{1})
if strcmpi(tested_template{1}, 'template_tomo_nonrigid')
%nonrigid tomo has data generation already included in the template
debug(1)
run(tested_template{1})
else
par = struct();
par.lamino_angle = 90; % default setting
% set debugging info level and marks
debug(1)
warning('off', 'MATLAB:mpath:nameNonexistentOrNotADirectory')
warning('off', 'MATLAB:dispatcher:pathWarning')
run(tested_template{1})
utils.verbose(-1,'Creating data')
% create "data"
if ~par.is_laminography
theta = pi+linspace(0, 180*(1-1/Nangles), Nangles);
else
Nangles = Nangles * 2;
theta = pi+linspace(0, 360*(1-1/Nangles), Nangles);
end
% create "N_subtomos" subtomos
theta = reshape(reshape(theta, N_subtomos,[])',1,[]);
par.subtomos = reshape(ones(Nangles/N_subtomos,N_subtomos).*[1:N_subtomos],1,[]);
% Add noise and offsets to the measured positions to make the
% alignment more difficult
position_errors = (0.1*randn(Nangles,2) + 0.1*sind(3*theta')) * Npix_vol(3);
asize = asize + ceil(max(asize, max(abs(position_errors)))/32)*32; % avoid the sample going out of FOV
par.asize = asize;
if par.lamino_angle == 90
Npix_proj = [Npix_vol(3), ceil(sqrt(2)*Npix_vol(1))]+asize;
max_sample_height = inf;
else
Npix_proj = ceil(sqrt(2)*Npix_vol([3,1]) .* [cosd(par.lamino_angle), 1] )+asize;
max_sample_height = 5e-6 ;
end
% provide other parameters required by the template
par.factor = 1;
par.factor_edensity = 1;
par.pixel_size = 50e-9;
par.scans_string = '';
par.output_folder = '???'; % some nonexistent folder, in default the template should not write any data during debug mode
obj_interf_pos_x = 0;
obj_interf_pos_y = 0;
delta_stack_prealign = [] ;
par.tilt_angle = 0;
par.skewness_angle = 0;
par.lambda = 0.2e-9;
par.scanstomo = 1:Nangles;
par.air_gap = [5,5];
par.GPU_list = GPU_id;
par.nresidua_per_frame = 0;
% generate geometry
Npix_vol(3) = min(Npix_vol(3),ceil(max_sample_height / par.pixel_size)-1);
CoR = Npix_proj/2 + position_errors;
[cfg, vectors] = astra.ASTRA_initialize(Npix_vol, Npix_proj, theta, par.lamino_angle, 'rotation_center', CoR);
% find optimal split, for small volumes below 600^3 no split is needed
split = astra.ASTRA_find_optimal_split(cfg);
par.illum_sum = ones(Npix_proj);
% generate complex projections
stack_object = tomo.Ax_sup_partial(utils.crop_pad_3D(volData, Npix_vol), cfg, vectors, split);
stack_object = stack_object / math.sp_quantile(stack_object, 0.99, 10);
if noise_level>0; stack_object = stack_object + noise_level * randn(size(stack_object)); end
stack_object = exp(-0.1*stack_object - 4i*stack_object);
object = stack_object(:,:,1);
if strcmpi(tested_template, 'template_tomo_recons_lamino')
% create errors in global geometry -> test automatic refinement
par.tilt_angle = -0.5;
par.skewness_angle = 0.5;
else
par.tilt_angle = 0;
par.skewness_angle = 0;
end
%% test stage 1: load test data and continue with the remplate
utils.verbose(-1,'Loading template "%s"', tested_template{1})
debug(2)
utils.verbose(struct('prefix', 'template'))
run(tested_template{1})
% check results of the geometry refinement provided by tests
if strcmpi(tested_template, 'template_tomo_recons_lamino')
assert(abs(par.tilt_angle) < 0.1 && abs(par.skewness_angle) < 0.1, 'Geometry refinement in laminography did not work well')
end
end
clearvars -except par tested_templates Nangles volData Npix_vol asize N_subtomos GPU_id noise_level test_astra test_mex_function test_simulated_data test_real_data base_path
end
%*-----------------------------------------------------------------------*
%|                                                                       |
%|  Except where otherwise noted, this work is licensed under a          |
%|  Creative Commons Attribution-NonCommercial-ShareAlike 4.0            |
%|  International (CC BY-NC-SA 4.0) license.                             |
%|                                                                       |
%|  Copyright (c) 2017 by Paul Scherrer Institute (http://www.psi.ch)    |
%|                                                                       |
%|      Author: CXS group, PSI  |
%*-----------------------------------------------------------------------*
% You may use this code with the following provisions:
%
% If the code is fully or partially redistributed, or rewritten in another
% computing language this notice should be included in the redistribution.
%
% If this code, or subfunctions or parts of it, is used for research in a
% publication or if it is fully or partially rewritten for another
% computing language the authors and institution should be acknowledged
% in written form in the publication: “Data processing was carried out
% using the “cSAXS matlab package” developed by the CXS group,
% Paul Scherrer Institut, Switzerland.”
% Variations on the latter text can be incorporated upon discussion with
% the CXS group if needed to more specifically reflect the use of the package
% for the published work.
%
% A publication that focuses on describing features, or parameters, that
% are already existing in the code should be first discussed with the
% authors.
%
% This code and subroutines are part of a continuous development, they
% are provided “as they are” without guarantees or liability on part
% of PSI or the authors. It is the user responsibility to ensure its
% proper use and the correctness of the results.